導讀
行文本輸入框在用於界面的文本輸入,在WEB登錄表單中應用廣泛。一般行文本編輯框可定制性較高,既可以當作密碼輸入框,又可以作為文本過濾器。QLineEdit本身使用方法也很簡單,無需過多的設置就能進行使用。於是這篇博文主要講解如何對行文本編輯框QLineEdit進行定制。
基本定制
為了簡化工作,還是如同前面所說的,直接用Qt Designer拖一個QLineEdit進行編輯。代碼部分不太多:
ui.lineEdit->setPlaceholderText(QStringLiteral("E-mail")); # 設定行編輯框的占位字符 ui.lineEdit->setFixedSize(155, 25);
看看效果:
下面編寫QSS代碼。先考慮下外觀應該定制的有哪些方面:邊框、背景色、圓角、鼠標懸停時、文本大小,大概差不多了:
QLineEdit { border: 1px solid rgb(41, 57, 85); # 邊框1px寬,顏色為深紫色 border-radius: 3px; # 給定3px邊框圓角 background: white; # 背景色定為白色吧 selection-background-color: green; # 這個屬性設定文本選中時的文本背景色 font-size: 14px ; # 文本的大小 } QLineEdit:hover { border: 1px solid blue; # 鼠標懸停時,我們將編輯框的邊框設置為藍色 }
效果還不錯。下面我們來看看行編輯框的另外一個應用:密碼輸入框。在默認情況下,當行編輯框用於密碼輸入時,其效果如下:
利用QSS中的lineedit-password-character屬性,我們可以更改密文顯示字符內容。QSS代碼如下:
QLineEdit[echoMode="2"] { lineedit-password-character: 35; }
注意到這里我們使用了一個屬性選擇器來進行選擇,就是當QLineEdit對象的echoMode屬性值為2時,我們將他們的密文顯示字符設置為其他值。這里我們設置成了35,這是一個ASCII碼值,在ASCII碼中對應字符為‘#’。因此:
當然,我們還可以換成其他的字符,如‘*’。‘*’對應的ASCII碼值為42,最終看起來將是:
當然,默認的圓點形式的密文還是更為常見。到底用哪種密文字符還是隨個人喜好了。另外,QLineEdit還有一個偽狀態:readonly,利用這個偽狀態,我們可以設置編輯框禁用時的外觀。
自動補全
自動補全是個非常人性化的功能。無論實在面向程序員的代碼編輯器中,還是面向終端用戶的軟件產品中,自動補全都能為工作效率和用戶體驗帶來極大的提升。文本編輯框的自動補全功能在數據過濾器中使用較為常見,用於過濾不相干數據直奔目標數據。在WEB表單中也經常可以看到其的身影,如下是騰訊某產品的一個注冊頁面:
當用戶輸入郵箱名的時候,編輯框會自動補全郵箱后綴部分。用戶輸入完郵箱名之后即可選擇郵箱類型,也可以讓用戶看到支持的郵箱類型。在WEB前端開發中,這樣的功能已經有相關的JS提供,直接調用就可以實現。我們接下來就是嘗試實現Qt版的郵箱補全功能。
說實話,Qt下面的自動補全功能實現起來更加簡單。因為Qt庫本身就提供了一個類QCompleter來完成這個功能。而且使用起來也很簡單,直接調用QLineEdit的setCompleter()即可完成。我們在實現代碼中添加如下代碼:
m_model = new QStandardItemModel(0, 1, this); m_completer = new QCompleter(m_model, this); ui.lineEdit->setCompleter(m_completer); connect(m_completer, SIGNAL(activated(const QString&)), this, SLOT(onEmailChoosed(const QString&))); connect(ui.lineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
在這里,我們使用了一個Model類來存儲數據。大致的原理就是,當用戶輸入發生變化時,我們將文本內容提取出來添加一個郵箱后綴並保存到Model類中。因為我們已經將這個Model類設置成了QCompleter類的Model,因此當我們更新Model類的數據時,QCompleter的下拉列表的內容也會同步更新。我們還要實現兩個槽函數來響應文本變化信號和列表項激活的信號:
void ThemeRoller::onEmailChoosed(const QString& email) { ui.lineEdit->clear(); // 清除已存在的文本更新內容 ui.lineEdit->setText(email); } void ThemeRoller::onTextChanged(const QString& str) { if (str.contains("@")) // 如果已經輸入了@符號,我們就停止補全了。因為到了這一步,我們再補全意義也不大了。 { return; } QStringList strlist; strlist << "@163.com" << "@qq.com" << "@gmail.com" << "@hotmail.com" << "@126.com"; m_model->removeRows(0, m_model->rowCount()); // 先清楚已經存在的數據,不然的話每次文本變更都會插入數據,最后出現重復數據 for (int i = 0; i < strlist.size(); ++i) { m_model->insertRow(0); m_model->setData(m_model->index(0, 0), str + strlist.at(i)); } }
如上代碼中的注釋所說,將信號activated()連接到槽onEmailChoosed()。當用戶用鼠標選擇了某一項之后就把選中的項更新到文本框中,補全完成。信號textChanged()連接到onTextChanged()用於更新Model中的數據。我們的做法也很簡單,在用戶的輸入文本后追加郵箱后綴再插入到model中去,這樣就實現了動態更新。
定制效果
實現起來還是挺簡單的。存在的一個缺陷是,當我們快速輸入或刪除文本時,補全列表偶爾會出現閃爍的跡象。這是由於數據更新造成的延遲現象。
小結
1. QLineEdit的外觀屬性,重要的屬性:lineedit-password-character.
2. QCompleter和QLineEdit搭配使用。