Question

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?

Was it helpful?

Solution

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!

OTHER TIPS

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()...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top