在插槽中调用QDialog :: exec会阻塞主事件循环吗?

时间:2015-11-09 08:37:02

标签: c++ qt blocking event-loop qeventloop

我的Qt应用程序的主窗口是一个普通的QMainWindow子类。在那个窗口我有几个按钮;每个信号都有clicked信号连接自己的插槽,每个插槽创建一个不同的QDialog,如下所示:

void onButtonA_clicked()
{
    MyADialog* dialog = new MyADialog(this);
    dialog->exec();
    delete dialog;
}

我一直在阅读这篇文章:https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop而作者说

  

你永远不应该阻止事件循环

让我担心的是; exec是一个阻塞函数,所以根据他所说的(他的Worker::doWork示例做了很多工作并需要一些时间来完成)我的代码阻止了事件循环,但我有没有注意到任何暗示这一点的东西;相反,主窗口似乎表现正常,当我更改代码以使用show()方法时没有区别。

我是否阻止事件循环?我应该在这里使用不同的方法吗?

1 个答案:

答案 0 :(得分:10)

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

需要注意可能存在的问题,并且在调用exec()时不要让应用程序处于不一致的状态,而不是依赖于之后的事情。

或者,拨打非阻止QDialog::open()并连接到finished()信号。