在插槽中调用QDialog :: exec是否会阻塞主事件循环? [英] Does calling QDialog::exec in a slot block the main event loop?

查看:601
本文介绍了在插槽中调用QDialog :: exec是否会阻塞主事件循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My Qt application's main window is a normal QMainWindow subclass. In that window I have a few buttons; each has its clicked signal connected its own slot, and each slot creates a different QDialog like so:

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

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

I've been reading this article: https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop and the author says

永远不要阻止事件循环

you should never ever block the event loop

这让我很担心; exec是一个阻止函数,所以根据他在那所说的(他的Worker::doWork示例需要大量工作,并且需要一些时间才能完成),我的代码阻止了事件循环,但是我没有注意到任何事情.会建议这一点;相反,主窗口似乎正常运行,并且当我更改代码以使用show()方法时没有任何区别.

which got me concerned; exec is a blocking function, so according to what he says there (his example with Worker::doWork which does a lot of work and needs some time to complete) my code is blocking the event loop, but I have not noticed anything that would suggest this; on the contrary, the main window seems to behave normally, and there was no difference when I changed the code to use the show() method.

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

Am I blocking the event loop? Should I use a different approach here?

推荐答案

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

QDialog::exec() blocks the main event loop, yes. It doesn't block the UI though, as it opens a local event loop inside exec(), which processes events while the dialog is open. That can be a source of nasty bugs: (Almost) anything can happen before exec() returns, external events (timers, network, IPC, whatever) can call slots, cause other dialogs to appear, etc. Just the ways for the user to do unexpected things directly are usually limited, given the modal nature of most such dialogs.

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

One needs to be aware of the possible issue and not leave the application in an inconsistent state when calling exec(), and not rely on things to be as they were afterwards.

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

Alternatively, call the non-blocking QDialog::open() and connect to the finished() signal.

这篇关于在插槽中调用QDialog :: exec是否会阻塞主事件循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆