1. 程式人生 > >Qt對話方塊中show和exec的區別

Qt對話方塊中show和exec的區別

QDialog的顯示有兩個函式show()和exec()。他們的區別在參考文件上的解釋如下:

show():
顯示一個非模式對話方塊。控制權即刻返回給呼叫函式。
彈出視窗是否模式對話方塊,取決於modal屬性的值。
(原文:Shows the dialog as a modeless dialog. Control returns immediately to the calling code.
The dialog will be modal or modeless according to the value of the modal property. )

exec():
顯示一個模式對話方塊,並且鎖住程式直到使用者關閉該對話方塊為止。函式返回一個DialogCode結果。
在對話方塊彈出期間,使用者不可以切換同程式下的其它視窗,直到該對話方塊被關閉。
(原文:Shows the dialog as a modal dialog, blocking until the user closes it. The function returns a DialogCode result.
Users cannot interact with any other window in the same application until they close the dialog. )

先簡單說一下我對模式和非模式對話方塊的一點點理解:
模式對話方塊,就是在彈出視窗的時候,整個程式就被鎖定了,處於等待狀態,直到對話方塊被關閉。這時往往是需要對話方塊的返回值進行下面的操作。如:確認視窗(選擇“是”或“否”)。
非模式對話方塊,在呼叫彈出視窗之後,呼叫即刻返回,繼續下面的操作。這裡只是一個呼叫指令的發出,不等待也不做任何處理。如:查詢框。

從字面上看,show()即可以顯示非模式也可以顯示模式對話方塊(設定modal值)。當modal=true的時候是否跟exec()就一樣了呢?
經過測試,還是有區別的。
使用show(),雖然在對話方塊彈出的時候,程式的其它操作(按鈕、視窗切換等)都失效了;但是程式仍然在呼叫對話方塊之後,馬上返回繼續執行後面的程式碼。這樣,你就不會得到視窗的返回值。以這個來看,show()只能算是“半模式”。
而使用exec(),在呼叫之後,程式就被鎖定在原地。等待視窗的關閉。

實際上,QDialog的show()函式來自其父類QWidget。而exec()則是自己的。

我最近特別喜歡繼承QWidget類來做彈出視窗,它的好處就是方便、靈活,既可以做為彈出視窗用也可以嵌入另外的頁面裡(QDialog是不行的)。但問題是,QWidget沒有exec()函式。所以想彈出這樣模擬出來的模式對話方塊就不行了。
也查過一些資料,有說用while(true)迴圈的,有說用接收事件的,但都感覺不太好。

所以,目前還沒有找到比較好的解決辦法。

續:
上面遺留的問題經過檢視QTE原始碼(沒有找到QT的)總算解決了。
我查看了QDialog類的exec()函式。發現裡面同樣呼叫了show(),只是在後面又呼叫了一句qApp->enter_loop()巢狀一個新的訊息迴圈來阻塞當前事件的執行;然後在hide()函式裡呼叫了qApp->exit_loop()來退出當前的訊息迴圈並繼續執行原事件。

到QT幫助裡查了一下這兩個函式,解釋如下:
enter_loop():
這個函式被廢棄了。它仍然被保留下來是為了使舊的程式碼能夠繼續工作。我們強烈建議不要在新寫的程式碼裡使用它。這個函式直接介入主訊息迴圈裡(遞迴地)。除非你真的知道你在做什麼,否則不要呼叫它。建議使用:QApplication::eventLoop()->enterLoop()。
exit_loop():
同樣被廢棄了。建議使用:QApplication::eventLoop()->exitLoop()。
提醒:這兩個操作都會進入主訊息迴圈,慎用!

那就按照建議的做吧,反正效果都是一樣的。修改原來的自定義視窗,在裡面增加了兩個函式,分別實現開啟和關閉視窗,封裝了eventLoop()的呼叫。程式碼如下:

#include <qapplication.h>
#include <qeventloop.h>
/*模擬QDialog::exec(),以模式對話方塊方式顯示*/
void MyWidget::doExec()
{
    this->show();
    in_loop = TRUE;
    //qApp->enter_loop();
    QApplication::eventLoop()->enterLoop();
}
/*關閉視窗*/
void MyWidget::doClose()
{
    if ( in_loop ) {
in_loop = FALSE;
//qApp->exit_loop();
        QApplication::eventLoop()->exitLoop();
    }
    this->close();
}

相關推薦

Qt對話方塊showexec區別

QDialog的顯示有兩個函式show()和exec()。他們的區別在參考文件上的解釋如下: show(): 顯示一個非模式對話方塊。控制權即刻返回給呼叫函式。 彈出視窗是否模式對話方塊,取決於modal屬性的值。 (原文:Shows the dia

QT對話方塊去掉幫助關閉按鈕 攔截QT關閉視窗的CloseEvent

建了一個對話方塊,我不想把邊框去掉,只想去掉關閉按鈕, setWindowFlags(windowFlags()&~Qt::WindowCloseButtonHint&~Qt::WindowContextHelpButtonHint); 結果那個問號的按鈕

Qt 的標準對話方塊(QColorDialogQInputDialog)

1、顏色對話方塊  Qt中提供了預定義的顏色對話方塊QColorDialog類  QColorDialog類用於提供指定顏色的對話方塊部件  顏色對話方塊的使用方式  Qt中的QColor類用來在程式中表示顏色的概念  QColor類同時支援多種顏色表示

QT】如何將QFileDialog對話方塊的英文內容轉化為中文

如何將QFileDialog對話方塊中的英文內容轉化為中文 在QT安裝目錄中找到相應的.qm檔案,如/usr/local/Trolltech/Qt-4.8.7/translations/qt_zh_CN.qm 在程式的入口函數出增加如下程式碼 #include &

子執行緒如何呼叫對話方塊的變數函式 2011-11-29 15:05

傳遞指標引數的方法:在對話方塊的初始化函式中呼叫子執行緒,將對話方塊指標this傳遞給執行緒pOdometerQueryThread=AfxBeginThread(&OdometerQueryThreadProc,this, THREAD_PRIORITY_NORMAL,0,0,NULL); 在子執行

關於Oracle執行儲存過程使用callexec區別說明

在sqlplus中這兩種方法都可以使用:  exec pro_name(引數1..);  call pro_name(引數1..);  區別:  1. 但是exec是sqlplus命令,只能在sqlplus中使用;call為SQL命令,沒有限制.  2. 儲存過程沒有

關於如何去除fckeditor圖片上傳對話方塊的連結高階兩個選項(轉帖)

 今天老闆要求修改一個網站後臺的編輯器,原因是原來的編輯老出問題,不好用。於是我就找了個現在很流行的fckedior來作為後臺的編輯器。    在做的過程中我碰到一個配置問題,上google上google搞了很久才成功。這個配置就是把圖片上傳對話方塊中的瀏覽器伺服器中的檔案功

Oracle執行儲存過程callexec區別

在sqlplus中這兩種方法都可以使用:  exec pro_name(引數1..); call pro_name(引數1..);  區別:  1. 但是exec是sqlplus命令,只能在sqlpl

子執行緒如何呼叫對話方塊的變數函式

因為執行緒函式是全域性的,而對話方塊的成員變數屬於對話方塊類,所以不能呼叫,若想使用,一方面可以將對話方塊指標作為引數傳遞給執行緒,另一方面可以在子執行緒中向主執行緒傳送訊息,然後在訊息響應函式裡呼叫想使用的對話方塊的函式和變數。 傳遞指標引數的方法:在對話方塊的初

《MFC&Qt混合程式設計》 part1 MFC對話方塊嵌入Qt視窗控制元件

《MFC&Qt混合程式設計》 part1 MFC對話方塊中嵌入Qt視窗控制元件 1、環境配置:VS2010,Qt4.8.4_win64,Qt_VS_Addin_1.1.11 2、建立的MFC對話方塊程式 3、輸出為x64的debug&r

Qt對話方塊/視窗、模態非模態、Qt::WA_DeleteOnClose

聊一聊Qt中,對話方塊/視窗、模態、非模態、獨立視窗釋放記憶體(設定視窗屬性為Qt::WA_DeleteOnClose)。 用得最多的就是對話方塊/視窗,QMainWindow、QWidget、QDi

Qt show()exec()

QDialog的顯示有兩個函式show()和exec()。他們的區別在參考文件上的解釋如下: show(): 顯示一個非模式對話方塊。控制權即刻返回給呼叫函式。 彈出視窗是否模式對話方塊,取決於modal屬性的值。 (原文:Shows the dialog as a modeless dialog.

Oracle call exec區別

今天發現了一個小東西,覺得很有意思,查找了一些資料,跟大家分享一下: 在sqlplus中: 在第三方提供的工具(如:plsqldev) 總結: exec是sqlplus的命令,

android彈出對話方塊帶有確定取消對話方塊帶事件的應用

上次看了一個關於android中對話方塊的使用,其中對帶確定和取消的對話方塊講的並不詳細,自己補全了一下,當確定和取消按鈕中有事件時的情況,沒事件時用null就行了 new AlertDialog.Builder(this).setTitle("標題").setMessag

(轉)Android 開發 對話方塊Dialog dismisshide方法的區別

原地址:https://www.pocketdigi.com/20120815/900.html dismiss和hide方法都可以隱藏對話方塊,在需要的時候也可以用show方法呼叫顯示。但是,這兩者是有區別的。 dismiss方法會釋放對話方塊所佔的資源,而hide

Oracle執行存儲過程callexec區別

completed pro spa 數據 -- gif insert ESS sqlplus命令 在sqlplus中這兩種方法都可以使用: exec pro_name(參數1..); call pro_name(參數1..); 區別: 1. 但是exec是sqlpl

mybatis的#$的區別

背景 插入 trac sql註入 -m .com article 參數 -s 1. #將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麽解析成sql時的值為order by "111", 如果傳

hibernatehql語句listiterate區別

每次 hibernate 寫入 所有 讀取 條件 iter 查詢 hql 1.使用list()方法獲取查詢結果,每次發出一條語句,獲取全部數據。2.使用iterate()方法獲取查詢結果,先發出一條SQL語句用來查詢滿足條件數據的id,然後依次按照這些id查詢記錄,也就是要

javaArrayListLinkedList區別

插入 list 新的 查找 arr tro 基於 列表 時間復雜度 ArrayList和LinkedList最主要的區別是基於不同數據結構 ArrayList是基於動態數組的數據結構,LinkedList基於鏈表的數據結構,針對這點,從時間復雜度和空間復雜度來看主要區別:

mysqlreplicate_wild_do_tablereplicate_do_db區別

lan rep cati mil 多人 pan think lte 避免 使用replicate_do_db和replicate_ignore_db時有一個隱患,跨庫更新時會出錯。 如在Master(主)服務器上設置 replicate_do_db=test(my.conf