前言
Qt中對話框是幾乎每個項目都會用到的GUI窗口對象。本文通過講解及其子類在項目中經常被用到的功能點,幫助小伙伴們理解和掌握其使用方法。
是Qt對話框類樹中的基類,Qt為我們提供了很多子類,即標準對話框,實現了豐富的對話框功能。下面我們先看一下本身需要關注的一些問題。
一句話描述模態對話框:
除模態對話框外,用戶無法選擇并操作其他窗口,只有關閉了模態對話框,用戶才能操作其他窗口。
下面的代碼,用::exec函數實現了模態對話框(請結合Qt中的類幫助文檔閱讀下面的代碼):
等效于
原理上,exec函數是阻塞執行的,直到模態對話框關閉才返回,可以看出,exec內部有一個自己的消息循環,一直在循環處理消息。用代碼模擬如下:
而調用show函數是不需要對話框關閉就會立即返回的,相當于(true),僅僅設置了允許窗口顯示的標記而已。先調用(true),再調用show()仍然是立即返回的,這種情況下,模態對話框使用的消息循環是main函數中app.exec中的啟動的應用全局消息循環。原理上嘗試理解即可,暫時不需要掌握,在后面的文章中會有對消息循環()的專門講解。
使用場景
exec阻塞執行方式,不會將本來可以在一個函數內實現的業務代碼,分散到多個函數中去。
比如下面的例子,彈出對話框讓用戶輸入名稱,然后校驗用戶輸入的用戶名是否正確,在一個函數內即可完成此功能:
如果使用show會怎么樣呢?使用show實現同樣的功能,代碼如下:
可以看到,使用show來顯示對話框,不僅要使用信號槽,還要添加成員變量、添加槽函數,非常麻煩,而且一個連續的業務流程代碼被分散到了多個函數中。
exec()是開發中最常用的模塊對話框調用方法。由上面的例子可知,模態對話框一般用來在某個處理過程中,請求用戶輸入內容,或配置必要的處理參數。而且,這樣可以保持業務處理代碼連續不分散。
非模態對話框
一句話描述非模態對話框:
非模態對話框不會獨占用戶鼠標和鍵盤輸入,用戶可以隨時在其他窗口和非模態窗口之間切換操作。
非模態對話框一般用來實現懸浮窗口。非模態對話框會懸浮在父窗口上層,父窗口通過構造函數的參數設置。即使點擊了父窗口,非模態對話框也會保持在父窗口上層,變化僅僅是失去焦點。
非模態對話框的典型例子是,使用文本編輯軟件如.exe,進行文本編輯時懸浮的文本搜索框,就是一種非模態對話框。
非模態對話框使用比較簡單,定義好對話框變量后,直接調用成員函數show即可顯示,這里不做過多講解。
子類
說完了,下面開始介紹子類。
Qt標準對話框
根據使用頻率大致對子類排序,見下表,讀者可根據此順序學習使用:
子類描述信息對話框,最常用,用于顯示提示信息、警告信息、詢問信息、致命信息,并接受用戶選擇下一步操作。文件對話框,常用,用于選擇文件、文件夾。輸入對話框,用于獲取字符串輸入、數值輸入、以及選擇列表中的某一項。、顏色和字體對話框。進度顯示對話框。錯誤信息顯示對話框,提供不再顯示某條內容的消息的選項。向導對話框,用于引導用戶進行某個操作。
自定義子類
自定義子類是必備技能。很多情況下,標準對話框不滿足使用要求,此時就需要我們自定義對話框實現響應的功能。
自定義對話框有以下幾點需要說明。
1. done、、
這三個函數是自定義函數一定需要用到的函數,用于控制以什么樣的狀態碼退出對話框。done函數用來退出對話框并設置退出碼。對于模態對話框,done相當于:
done結束對話框內部消息循環,done函數退出模態對話框是什么時候實例的對話框,隨后下一個消息循環中,exec函數中的消息循環返回,exec函數也退出,最后返回到調用對話框的代碼處。
相當于
相當于
2. 不要用exec的返回值來傳遞內容信息
exec的返回值可以用來傳遞退出碼。由上述內容可知,done、、可以用來退出對話框并設置退出碼。
筆者在初次自定義對話框時,總想著將對話框中的輸入內容,用exec返回。例如,將用戶在對話框中選擇的列表項索引,用done(index)來返回。這里明確地告訴小伙伴們模態對話框是什么時候實例的對話框,這樣的用法是不提倡的。因為如果是字符串,那怎么返回呢?
正確的做法是,使用done返回用戶對編輯的確認狀態,即確認設置內容還是取消設置,確認內容用,取消設置用。這樣一來,自定義的類需要提供對話框數據獲取接口,當exec返回后,再使用對話框對象實例,調用數據獲取接口獲取用戶編輯的數據。
舉個簡單的例子:
結語
本文代碼略多,粗略地講解了Qt中對話框的類型和理解對話框工作原理的關鍵問題。細節的部分需要讀者自己去實踐,文章中無法講解得太過詳細。講解太過詳細,第一,讀起來費時費力,倒不如花時間自己寫代碼嘗試,第二,學習容易出現問題的地方是較難理解的地方,細節不需要面面俱到 ,用到的時候再查就可以。學習Qt某個模塊,要先把握住某一個功能模塊的運作機理、框架,而不是一頭鉆進龐雜的內容里,沒有方向地去學習,效率很低也很痛苦。
本文是Qt基礎文章,筆者想盡快寫完Qt的基礎部分,除了基礎還有很多東西需要掌握,不能一直在基礎上轉圈圈。小伙伴們如果有疑問,歡迎留言。如果問題很多,筆者會考慮建一個討論群,盡自己能力幫助想要學習Qt的同學,大家一起進步。
本文首發于微信公眾號“Qt未來工程師”。