Does calling QDialog::exec in a slot block the main event loop?
我的Qt应用程序的主窗口是普通的QMainWindow子类。 在那个窗口中,我有几个按钮。 每个插槽都有连接其clicked信号的信号,并且每个插槽都创建一个不同的QDialog,如下所示:
1 2 3 4 5 6
| void onButtonA_clicked()
{
MyADialog* dialog = new MyADialog(this);
dialog->exec();
delete dialog;
} |
我一直在阅读这篇文章:https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop和作者说
you should never ever block the event loop
这让我很担心; exec是一个阻止函数,所以根据他在那所说的(他的Worker::doWork示例需要大量工作并且需要一些时间才能完成),我的代码阻止了事件循环,但是我没有注意到任何事情。 会建议这一点; 相反,主窗口似乎正常运行,并且当我更改代码以使用show()方法时没有任何区别。
我是否阻止了事件循环? 我应该在这里使用其他方法吗?
-
据我所知,int QDialog::exec()不会阻止Qt应用程序,只会阻止父窗口,并且仅当对话框是窗口模式时才阻止。
-
@Tarod嗯,它是一个阻塞函数(因为它直到QDialog关闭才返回),这就是为什么我不确定的原因。
QDialog::exec()阻止主事件循环,是的。 但是,它不会阻止UI,因为它在exec()内打开了一个本地事件循环,该循环在打开对话框时处理事件。 这可能是令人讨厌的错误的来源:(几乎)在exec()返回之前,可能发生任何事情,外部事件(计时器,网络,IPC等)可以调用插槽,导致其他对话框出现,等等。这只是用户的方式 鉴于大多数此类对话框的模态性质,直接限制其直接执行意外事件通常受到限制。
人们需要意识到可能的问题,并且在调用exec()时不要使应用程序处于不一致的状态,并且不要依赖事后的状况。
或者,调用非阻塞QDialog::open()并连接到finished()信号。
-
后续问题-将QMessageBox与exec()一起使用时,是否会出现相同情况? 用静态函数API实例化的QMessageBox怎么样:即int ret = QMessageBox :: warning ...
-
以上所有@riverofwind也适用于此