【技术】Qt对话框讲解
前言
Qt中對(duì)話框QDialog是幾乎每個(gè)項(xiàng)目都會(huì)用到的GUI窗口對(duì)象。本文通過講解QDialog及其子類在項(xiàng)目中經(jīng)常被用到的功能點(diǎn),幫助小伙伴們理解和掌握其使用方法。
QDialog
QDialog是Qt對(duì)話框類樹中的基類,Qt為我們提供了很多QDialog子類,即標(biāo)準(zhǔn)對(duì)話框,實(shí)現(xiàn)了豐富的對(duì)話框功能。下面我們先看一下QDialog本身需要關(guān)注的一些問題。
模態(tài)對(duì)話框
一句話描述模態(tài)對(duì)話框:
除模態(tài)對(duì)話框外,用戶無法選擇并操作其他窗口,只有關(guān)閉了模態(tài)對(duì)話框,用戶才能操作其他窗口。
下面的代碼,用QDialog::exec函數(shù)實(shí)現(xiàn)了模態(tài)對(duì)話框(請(qǐng)結(jié)合Qt中QDialog的類幫助文檔閱讀下面的代碼):
QDialog dlg; dlg.exec(); // 執(zhí)行模態(tài)對(duì)話框等效于
QDialog dlg; dlg.setModel(true); // 設(shè)置為模態(tài) dlg.show(); // 顯示對(duì)話框原理上,exec函數(shù)是阻塞執(zhí)行的,直到模態(tài)對(duì)話框關(guān)閉才返回,可以看出,exec內(nèi)部有一個(gè)自己的消息循環(huán),一直在循環(huán)處理消息。用代碼模擬如下:
class QDialog { public:int exec(){show(); // 顯示窗口m_event_loop.exec(); // 事件循環(huán)hide(); // 隱藏窗口return result(); // 返回退出碼}private:QEventLoop m_event_loop; // 事件循環(huán)對(duì)象 }而調(diào)用show函數(shù)是不需要對(duì)話框關(guān)閉就會(huì)立即返回的,相當(dāng)于setVisible(true),僅僅設(shè)置了允許窗口顯示的標(biāo)記而已。先調(diào)用setModel(true),再調(diào)用show()仍然是立即返回的,這種情況下,模態(tài)對(duì)話框使用的消息循環(huán)是main函數(shù)中app.exec中的啟動(dòng)的應(yīng)用全局消息循環(huán)。原理上嘗試?yán)斫饧纯?#xff0c;暫時(shí)不需要掌握,在后面的文章中會(huì)有對(duì)消息循環(huán)(QEventLoop)的專門講解。
使用場景
exec阻塞執(zhí)行方式,不會(huì)將本來可以在一個(gè)函數(shù)內(nèi)實(shí)現(xiàn)的業(yè)務(wù)代碼,分散到多個(gè)函數(shù)中去。
比如下面的例子,彈出對(duì)話框讓用戶輸入名稱,然后校驗(yàn)用戶輸入的用戶名是否正確,在一個(gè)函數(shù)內(nèi)即可完成此功能:
class Test { public:void checkUsername(){QString name;MyDialog dlg; // MyDialog為我們自定義的QDialog子類// 用戶點(diǎn)擊取消按鈕,直接返回if (dlg.exec() == QDialog::Rejected) {return;}name = dlg.getName(); // 獲取用戶名if (name != "ABC") // 校驗(yàn)用戶名{qDebug() << "Name Error!"; // 用戶名校驗(yàn)錯(cuò)誤return;}else{qDebug() << "Pass"; // 用戶名校驗(yàn)正確}} }如果使用show會(huì)怎么樣呢?使用show實(shí)現(xiàn)同樣的功能,代碼如下:
class Test : public QObject {Q_OBJECT public:void showNameInputDialog(){ // 下面額外監(jiān)聽對(duì)話框關(guān)閉信號(hào)connect(&m_dlg, SIGNAL(finished(int)), this, SLOT(slotDialogFinished(int)));m_dlg.setModel(true);m_dlg.show();}// 響應(yīng)對(duì)話框關(guān)閉信號(hào)的槽void slotDialogFinished(int code){if (code == QDialog::Rejected) // 用戶點(diǎn)擊取消按鈕,直接返回{return;}name = m_dlg.getName(); // 獲取用戶名if (name != "ABC") // 校驗(yàn)用戶名{qDebug() << "Name Error!";return;}else{qDebug() << "Pass"; // 用戶名校驗(yàn)正確}}private:// MyDialog為我們自定義的QDialog子類// 需要延長dlg的生命周期,把exec例子中的函數(shù)內(nèi)變量,寫成類的成員變量MyDialog m_dlg; }可以看到,使用show來顯示對(duì)話框,不僅要使用信號(hào)槽,還要添加成員變量、添加槽函數(shù),非常麻煩,而且一個(gè)連續(xù)的業(yè)務(wù)流程代碼被分散到了多個(gè)函數(shù)中。
exec()是開發(fā)中最常用的模塊對(duì)話框調(diào)用方法。由上面的例子可知,模態(tài)對(duì)話框一般用來在某個(gè)處理過程中,請(qǐng)求用戶輸入內(nèi)容,或配置必要的處理參數(shù)。而且,這樣可以保持業(yè)務(wù)處理代碼連續(xù)不分散。
非模態(tài)對(duì)話框
一句話描述非模態(tài)對(duì)話框:
非模態(tài)對(duì)話框不會(huì)獨(dú)占用戶鼠標(biāo)和鍵盤輸入,用戶可以隨時(shí)在其他窗口和非模態(tài)窗口之間切換操作。
非模態(tài)對(duì)話框一般用來實(shí)現(xiàn)懸浮窗口。非模態(tài)對(duì)話框會(huì)懸浮在父窗口上層,父窗口通過構(gòu)造函數(shù)的parent參數(shù)設(shè)置。即使點(diǎn)擊了父窗口,非模態(tài)對(duì)話框也會(huì)保持在父窗口上層,變化僅僅是失去焦點(diǎn)。
非模態(tài)對(duì)話框的典型例子是,使用文本編輯軟件如notepad.exe,進(jìn)行文本編輯時(shí)懸浮的文本搜索框,就是一種非模態(tài)對(duì)話框。
非模態(tài)對(duì)話框使用比較簡單,定義好對(duì)話框變量后,直接調(diào)用成員函數(shù)show即可顯示,這里不做過多講解。
QDialog子類
說完了QDialog,下面開始介紹QDialog子類。
Qt標(biāo)準(zhǔn)對(duì)話框
根據(jù)使用頻率大致對(duì)QDialog子類排序,見下表,讀者可根據(jù)此順序?qū)W習(xí)使用:
| QMessageBox | 信息對(duì)話框,最常用,用于顯示提示信息、警告信息、詢問信息、致命信息,并接受用戶選擇下一步操作。 |
| QFileDialog | 文件對(duì)話框,常用,用于選擇文件、文件夾。 |
| QInputDialog | 輸入對(duì)話框,用于獲取字符串輸入、數(shù)值輸入、以及選擇列表中的某一項(xiàng)。 |
| QColorDialog、QFontDialog | 顏色和字體對(duì)話框。 |
| QProgressDialog | 進(jìn)度顯示對(duì)話框。 |
| QErrorMessage | 錯(cuò)誤信息顯示對(duì)話框,提供不再顯示某條內(nèi)容的消息的選項(xiàng)。 |
| QWizard | 向?qū)?duì)話框,用于引導(dǎo)用戶進(jìn)行某個(gè)操作。 |
自定義QDialog子類
自定義QDialog子類是必備技能。很多情況下,標(biāo)準(zhǔn)對(duì)話框不滿足使用要求,此時(shí)就需要我們自定義對(duì)話框?qū)崿F(xiàn)響應(yīng)的功能。
自定義對(duì)話框有以下幾點(diǎn)需要說明。
1. done、accept、reject
這三個(gè)函數(shù)是自定義函數(shù)一定需要用到的函數(shù),用于控制以什么樣的狀態(tài)碼退出對(duì)話框。
done函數(shù)用來退出對(duì)話框并設(shè)置退出碼。
對(duì)于模態(tài)對(duì)話框,done相當(dāng)于:
done結(jié)束對(duì)話框內(nèi)部消息循環(huán),done函數(shù)退出,隨后下一個(gè)消息循環(huán)中,exec函數(shù)中的消息循環(huán)返回,exec函數(shù)也退出,最后返回到調(diào)用對(duì)話框的代碼處。
accept相當(dāng)于
done(QDialog::Accepted);reject相當(dāng)于
done(QDialog::Rejected);2. 不要用exec的返回值來傳遞內(nèi)容信息
exec的返回值可以用來傳遞退出碼。由上述內(nèi)容可知,done、accept、reject可以用來退出對(duì)話框并設(shè)置退出碼。
筆者在初次自定義對(duì)話框時(shí),總想著將對(duì)話框中的輸入內(nèi)容,用exec返回。例如,將用戶在對(duì)話框中選擇的列表項(xiàng)索引,用done(index)來返回。這里明確告訴小伙伴們這樣的用法是不提倡的。因?yàn)槿绻亲址?#xff0c;那怎么返回呢?
正確的做法是,使用done返回用戶對(duì)編輯的確認(rèn)狀態(tài),即確認(rèn)設(shè)置內(nèi)容還是取消設(shè)置,確認(rèn)內(nèi)容用accept,取消設(shè)置用reject。這樣一來,自定義的QDialog類需要提供對(duì)話框數(shù)據(jù)獲取接口,當(dāng)exec返回后,再使用對(duì)話框?qū)ο髮?shí)例,調(diào)用數(shù)據(jù)獲取接口獲取用戶編輯的數(shù)據(jù)。
舉個(gè)簡單的例子:
class MyDialog : public QDialog { public:explicit MyDialog(QWidget *parent = NULL);QString getName(){// 從界面輸入框中獲取用戶輸入內(nèi)容return ui->lineEdit_name->text();}QString getPassword(){// 從界面輸入框中獲取用戶輸入內(nèi)容return ui->lineEdit_password->text();}private:// 點(diǎn)擊確認(rèn)按鈕響應(yīng)void slotOkButtonClicked(){accept();}// 點(diǎn)擊取消按鈕響應(yīng)void slotCancelButtonClicked(){reject();} }結(jié)語
本文代碼略多,粗略地講解了Qt中對(duì)話框的類型和理解對(duì)話框工作原理的關(guān)鍵問題。細(xì)節(jié)的部分需要讀者自己去實(shí)踐,文章中無法講解得太過詳細(xì)。講解太過詳細(xì),第一,讀起來費(fèi)時(shí)費(fèi)力,倒不如花時(shí)間自己寫代碼嘗試,第二,學(xué)習(xí)容易出現(xiàn)問題的地方是較難理解的地方,細(xì)節(jié)不需要面面俱到 ,用到的時(shí)候再查就可以。學(xué)習(xí)Qt某個(gè)模塊,要先把握住某一個(gè)功能模塊的運(yùn)作機(jī)理、框架,而不是一頭鉆進(jìn)龐雜的內(nèi)容里,沒有方向地去學(xué)習(xí),效率很低也很痛苦。
本文是Qt基礎(chǔ)文章,筆者想盡快寫完Qt的基礎(chǔ)部分,除了基礎(chǔ)還有很多東西需要掌握,不能一直在基礎(chǔ)上轉(zhuǎn)圈圈。小伙伴們?nèi)绻幸蓡?#xff0c;歡迎留言。如果問題很多,筆者會(huì)考慮建一個(gè)討論群,盡自己能力幫助想要學(xué)習(xí)Qt的同學(xué),大家一起進(jìn)步。
本文首發(fā)于微信公眾號(hào)“Qt未來工程師”。
總結(jié)
以上是生活随笔為你收集整理的【技术】Qt对话框讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机组成与系统原理中的节拍是什么意思?
- 下一篇: Win10上VMware的问题汇总