QThread/QDialog 的竞争条件
我试图避免以下情况下的竞争条件:
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
当线程在 QDialog::exec() 设置对话框之前完成时,由信号触发的“accept()”调用将丢失并且对话框不会自行关闭...
所以理想情况下,我只想在对话框准备好处理它之后才启动线程,但我该怎么做呢?
I'm trying to avoid a race condition in the following scenario:
QDialog* dialog = [...];
QThread* thread = [...];
connect(thread, SIGNAL(finished()), dialog, SLOT(accept()));
thread->start();
dialog->exec();
When the thread finishes before QDialog::exec() has set up the dialog, the "accept()" call that was triggered by the signal will be lost and the dialog will not close itself...
So ideally I want to start the thread only after the dialog is ready to handle it, but how would I do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
技巧是只有当对话框已经显示时才必须启动线程。所以你必须在引发 QDialog 的 showEvent 后启动它。
首先,您必须捕获 showEvent,您可以通过使用
QObject::installEventFilter
和QObject::eventFilter
或通过子类化QDialog
重写来完成此操作QWidget::showEvent
。完成此操作后,您需要向线程发出启动信号。您需要一个自定义信号,您可以在
YourClass::eventFilter
或YourClass::showEvent
中发出该信号,具体取决于您选择捕获显示事件的方式。现在只需将该信号连接到 QThread::start() 插槽即可完成(编辑:使用 Qt::QueuedConnection)。
确保您没有两次处理
QDialog::accepted()
信号!The trick is that you have to start the thread only when the dialog is shown already. so you have to start it once the showEvent of the QDialog is raised.
First you have to capture the showEvent, you can do this by either using
QObject::installEventFilter
andQObject::eventFilter
or by subclassingQDialog
overridingQWidget::showEvent
.Once you have done that, you want to signal the thread to start. You need a custom signal, which you emit in
YourClass::eventFilter
or inYourClass::showEvent
depending which way you chose to capture the show event.Now simply connect that signal to the
QThread::start()
slot and you should be done (EDIT: use aQt::QueuedConnection
).Make sure you dont handle the
QDialog::accepted()
signal twice!自从我使用 Qt 以来已经有一段时间了。但是为什么要使用 QThread 来处理对话框中的“接受”单击呢?如果它是模式对话框,您可以使用 QDialog::result(),或者您可以将信号从线程转发到 QDialog::accepted()...
Was a while since I used Qt. But why are you using a QThread to handle the Accept click from the dialog? You can use QDialog::result() if it's a modal dialog or you can forward the signal from the thread to QDialog::accepted()...