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?
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
and QObject::eventFilter
or by subclassing QDialog
overriding QWidget::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 in YourClass::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 a Qt::QueuedConnection
).
Make sure you dont handle the QDialog::accepted()
signal twice!