Qt中,最后的return x.exec()都做了哪些工作

程序進(jìn)行消息循環(huán),等待可能輸入進(jìn)行響應(yīng)

話題一:QDialog的show()和exec()定義

** 1. show()**
顯示一個(gè)模式對(duì)話框。控制權(quán)即刻返回給調(diào)用函數(shù)。彈出窗口是否模式對(duì)話框,取決于modal屬性的值。
** 2. exec()**
顯示一個(gè)模式對(duì)話框,并且鎖住程序直到用戶關(guān)閉該對(duì)話框?yàn)橹?。函?shù)返回一個(gè)DialogCode結(jié)果。
在對(duì)話框彈出期間,用戶不可切換同程序下的其它窗口,直到該對(duì)話框被關(guān)閉。
** 3. 模式和非模式對(duì)話框**
模式對(duì)話框:彈出窗口的時(shí)候,整個(gè)程序就被鎖定了,處于等待狀態(tài),直到對(duì)話框被關(guān)閉。這時(shí)往往是需要對(duì)話框的返回值進(jìn)行下面的操作。如:確認(rèn)窗口(選擇“是”或“否”)。
非模式對(duì)話框:彈出窗口之后,調(diào)用即刻返回,繼續(xù)下面的操作。這里只是一個(gè)調(diào)用指令的發(fā)出,不等待也不做任何處理。如:查找框。show()即可以顯示非模式也可以顯示模式對(duì)話框(設(shè)置modal值)。當(dāng)modal=true的時(shí)候是否跟exec()就一樣了呢?經(jīng)過(guò)測(cè)試,還是有區(qū)別的。使用show(),雖然在對(duì)話框彈出的時(shí)候,程序的其它操作(按鈕、窗口切換等)都失效了;但是程序仍然在調(diào)用對(duì)話框之后,馬上返回繼續(xù)執(zhí)行后面的代碼。這樣,你就不會(huì)得到窗口的返回值。
使用exec(),在調(diào)用之后,程序就被鎖定在原地。等待窗口的關(guān)閉。

二.QWidget實(shí)現(xiàn)模式對(duì)話框
QDialog的show()函數(shù)來(lái)自其父類QWidget。而exec()則是自己的。
繼承QWidget類來(lái)做彈出窗口,它的好處就是方便、靈活,既可以做為彈出窗口用也可以嵌入另外的頁(yè)面里(QDialog是不行的)。但問(wèn)題是,QWidget沒(méi)有exec()函數(shù)。所以想彈出這樣模擬出來(lái)的模式對(duì)話框就不行了。
也查過(guò)一些資料,有說(shuō)用while(true)循環(huán)的,有說(shuō)用接收事件的,但都感覺(jué)不太好。
查看了QDialog類的exec()函數(shù)。發(fā)現(xiàn)里面同樣調(diào)用了show(),只是在后面又調(diào)用了一句qApp->enter_loop()嵌套一個(gè)新的消息循環(huán)來(lái)阻塞當(dāng)前事件的執(zhí)行;然后在hide()函數(shù)里調(diào)用了qApp->exit_loop()來(lái)退出當(dāng)前的消息循環(huán)并繼續(xù)執(zhí)行原事件。
到QT幫助里查了一下這兩個(gè)函數(shù),解釋如下:
enter_loop():
這個(gè)函數(shù)被廢棄了。它仍然被保留下來(lái)是為了使舊的代碼能夠繼續(xù)工作。我們強(qiáng)烈建議不要在新寫的代碼里使用它。這個(gè)函數(shù)直接介入主消息循環(huán)里(遞歸地)。除非你真的知道你在做什么,否則不要調(diào)用它。建議:QApplication::eventLoop()->enterLoop()。
exit_loop():
同樣被廢棄了。建議使用:QApplication::eventLoop()->exitLoop()。
提醒:這兩個(gè)操作都會(huì)進(jìn)入主消息循環(huán),慎用!
那就按照建議的做吧,反正效果都是一樣的。修改原來(lái)的自定義窗口,在里面增加了兩個(gè)函數(shù),分別實(shí)現(xiàn)打開(kāi)和關(guān)閉窗口,封裝了eventLoop()的調(diào)用。代碼如下:

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

綜上所述:QWidget實(shí)現(xiàn)模式對(duì)話框exec()[1],內(nèi)部機(jī)制為enter_loop() 即先進(jìn)行對(duì)話框函數(shù)內(nèi)部循環(huán),完成自己函數(shù)體內(nèi)容,再執(zhí)行exit_loop()退出函數(shù)體循環(huán)。類似Objective-C語(yǔ)言的runtime機(jī)制


  1. QDialog實(shí)現(xiàn)對(duì)話框的模式狀態(tài):在該對(duì)話框打開(kāi)未關(guān)閉之前,別的對(duì)話框(窗體)無(wú)法進(jìn)行操作。 ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容