亂談Qt事件迴圈巢狀

2021-08-07 09:50:42 字數 2363 閱讀 5854

**:

int main(int argc, char**argv)

但是在同乙個執行緒內,我們可以開啟多個事件迴圈,比如通過:

這些東西都很常用,不是麼?它們每乙個裡面都在執行這樣的語句:

qeventloop loop;     //事件迴圈

loop.exec();

既然是同一執行緒內,這些顯然是無法並行執行的,那麼只能是巢狀執行。

如何用最小的例子來直觀說明這個問題呢?

利用定時器來演示應該是最方便的。於是,很容易寫出來這樣的**:

#include 

class object : public qobject

protected:

void timerevent(qtimerevent *)

};int main(int argc, char *argv)

然後我們可以期待看到:

enter: 1

enter: 2

enter: 3

...

但是,很讓人失望,這並不會工作。因為qt對timer事件派發時進行了處理:

我們對這個例子進行一點改進:

另外,為了友好一點,使用了 qplaintextedit 來顯示結果:

#include #include 

class widget : public qplaintextedit

protected:

bool event(qevent * evt)

else if (evt->type() == qevent::user)

return qplaintextedit::event(evt);

}};int main(int argc, char *argv)

這個例子確實沒有什麼,因為似乎沒人會寫這樣的**。

但是,當你呼叫

等函式時,實際上就啟動了巢狀的事件迴圈,而如果不小心的話,還有遇到各種怪異的問題!

== qdialog::exec() vs qdialog::open()== 在 qdialog 模態對話方塊與事件迴圈 以及 

漫談qwidget及其派生類(四) 我們解釋過qdialog::exec()。它最終就是呼叫qeventloop::exec()。

qdialog::exec()這個東西是這麼常用,以至於我們很少考慮這個東西的不利因素。qdialog::open()儘管被官方所推薦,但是似乎很少有人用,很多人可能還不知道它的存在。

但是qt官方blog中:

一文介紹了 exec() 可能造成的危害,並鼓勵大家使用 qdialog::open()

對qdialog::open()有詳細的介紹

看個例子:我們通過顏色對話方塊選擇乙個顏色,

void widget::on***clicked()

void widget::on***clicked()

void widget::on***clicked()

void widget::dialogclosed(const qcolor &color)

好處嘛(就摘錄andreas aardal hanssen的話吧):

kde開發者官方blog中描述這個問題:

在某個槽函式中,我們通過qdialog::exec() 彈出乙個對話方塊。

void parentwidget::slotdosomething() 

}

如果這時parentwidget或者通過其他方式(比如dbus)得到通知,需要被關閉。會怎麼樣?

程式將崩潰:parentwidget析構時,將會delete這個對話方塊,而這個對話方塊卻在棧上。

簡單模擬一下(在上面**中加一句即可):

void parentwidget::slotdosomething() 

else if(!dlg)

if (!dlg)

}

感興趣的可以去看看原文。比較起來 qdialog::open() 應該更值得考慮。

當程式做繁重的操作時,而又不願意開啟乙個新執行緒時,我們都會選擇呼叫

來使得程式保持相應。這和前面提到的哪些exec()開啟區域性事件迴圈的效果其實是完全一樣的。

無論是這個,還是qeventloop::exec()最終都是呼叫:

qabstracteventdispatcher::processevents()

來進行事件派發。前面的問題也都是由它派發的事件引起的。

亂談Qt事件迴圈巢狀

int main int argc,char argv 但是在同乙個執行緒內,我們可以開啟多個事件迴圈,比如通過 這些東西都很常用,不是麼?它們每乙個裡面都在執行這樣的語句 qeventloop loop 事件迴圈 loop.exec 既然是同一執行緒內,這些顯然是無法並行執行的,那麼只能是巢狀執行...

亂談Qt事件迴圈巢狀

int main int argc,char argv 但是在同乙個執行緒內,我們可以開啟多個事件迴圈,比如通過 這些東西都很常用,不是麼?它們每乙個裡面都在執行這樣的語句 qeventloop loop 事件迴圈 loop.exec 既然是同一執行緒內,這些顯然是無法並行執行的,那麼只能是巢狀執行...

QT事件迴圈

什麼是自發事件?哪些型別的事件可以被propagated 或compressed?posting and sending 事件之間有何不同?什麼時候應該呼叫 accept 或是ignore 如果這些問題你還不是很了解,那麼繼續看下去。事件起源 定製事件型別 到現在為至,我們所說的內容不僅僅適用於ke...