关于c ++:在插槽中调用QDialog :: exec是否会阻塞主事件循环?

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()方法时没有任何区别。

我是否阻止了事件循环? 我应该在这里使用其他方法吗?


QDialog::exec()阻止主事件循环,是的。 但是,它不会阻止UI,因为它在exec()内打开了一个本地事件循环,该循环在打开对话框时处理事件。 这可能是令人讨厌的错误的来源:(几乎)在exec()返回之前,可能发生任何事情,外部事件(计时器,网络,IPC等)可以调用插槽,导致其他对话框出现,等等。这只是用户的方式 鉴于大多数此类对话框的模态性质,直接限制其直接执行意外事件通常受到限制。

人们需要意识到可能的问题,并且在调用exec()时不要使应用程序处于不一致的状态,并且不要依赖事后的状况。

或者,调用非阻塞QDialog::open()并连接到finished()信号。