PDA

View Full Version : QDialog - show(), exec() and blocking



xdn
9th April 2015, 14:56
Hi,

I just came across a widget with the following code in one of its methods (slightly paraphrased):


void MyWidget::showDialog()
{
Ui_Dialog dui;
QDialog dialog;
dui.setupUi(&dialog);
// some more stuff to setup dialog
dialog.show();
if (dialog.exec() == QDialog::Accepted)
{
// store dialog content somewhere
}
qDebug() << "END";
}


I'm rather surprised by the show() followed by an exec() which I've never seen before in this way.
What seems to happen is that the new dialog does not block the parent widget, because of the show().
I don't understand why a previous show() should have an impact on the behaviour of exec().
MyWidget remains responsive yet the rest of showDialog() does not get executed (no "END" is printed) until the dialog is closed (then it does get printed).
So basically the method seems to pause at the exec() yet MyWidget is responsive?!
Of course this leads to segmentation faults, if MyWidget gets closed before the dialog is closed.

If I comment out the show(), the exec() properly blocks and everything works pretty much as I would expect.

Is there any reason to use show() and exec() in this way (in any situation)?
Is it a wanted behaviour that a previous show() influences exec() in this way?
Isn't the correct way to open a dialog and remain responsive to connect a slot to the dialog's finished() method (and have the dialog be a member instead of a local variable)?

Best,
xdn

anda_skoa
9th April 2015, 16:58
show() is totally unnecessary here, exec() calls show() internally.

exec() runs a nested event loop which processes all applications events just like the main event loop but filters out all user events targetted at the dialog's parent.
A so called modal dialog.

Caling just show() creates a non-modal dialog, which, as you correctly assumed, would need to be stored in a member variable instead of on the slot's stack.

But either way is correct, it depends on the use case of the dialog.

Not that the code you have there isn't horrible in other ways, the stray show() is the smallest problem

Cheers,
_

xdn
15th April 2015, 12:01
Not that the code you have there isn't horrible in other ways, the stray show() is the smallest problem


Hi again,

thanks for clearing that up for me.
I am interested in what else you think is horrible in that code snippet.

Best,
xdn

anda_skoa
15th April 2015, 13:29
This part


Ui_Dialog dui;
QDialog dialog;
dui.setupUi(&dialog);


The proper way to have a custom dialog is to derive from QDialog and do the UI setup in its constructor.
Which is, not incidentally, also the way QtCreator's "New UI Form class" template works.

The code using the dialog should not have to care about setting up dialog internals.

Cheers,
_

xdn
17th April 2015, 09:51
Ok, will fix that part as well.
Thanks for all the help.