QDialog: show() and exec() together in constructor?
I'm using a QDialog. In the constructor I need to do some time-consuming stuff. Therfore it looks like this:
constructor
{
initialize widgets, buttons, etc.
mydialog->show();
do some timeconsuming stuff
mydialog->exec();
}
My question is, is it valid/legal to use show() and exec() in the same constructor?
I tried and everything works well but I want to know for sure.
Re: QDialog: show() and exec() together in constructor?
Em..interesting question :) Yes its correct, but why do you need it ?
exec() - show your dialog as modal window;
show() - show your dialog as standart widget;
Re: QDialog: show() and exec() together in constructor?
Hmm, I doubt it does what it's intended to do. Calling show() doesn't show the dialog immediately but schedules a show event which the dialog will receive later when the control returns to the event loop. Calling exec() makes the dialog appear because the dialog will start it's own event loop.
Re: QDialog: show() and exec() together in constructor?
exec() blocks till the dialog gets closed, show() doesn't.
If I do like this:
Code:
constructor
{
initialize widgets, buttons, etc.
do some timeconsuming stuff
mydialog->exec();
}
it will take a long time till the user sees the dialog because of the time consuming stuff in the constructor.
If I do like this:
Code:
constructor
{
initialize widgets, buttons, etc.
mydialog->exec();
do some timeconsuming stuff
}
then the timeconsuming stuff will be done AFTER the user closed the dialog
If I do like this:
Code:
constructor
{
initialize widgets, buttons, etc.
mydialog->show();
do some timeconsuming stuff
}
then the parent window/widget will continue (the dialog will not block) and that's not what I want.
Regards.
Re: QDialog: show() and exec() together in constructor?
Quote:
Originally Posted by
Teuniz
exec() blocks till the dialog gets closed, show() doesn't.
Yes, that's the difference between modal and modeless dialogs. But calling show() before the time consuming task doesn't bring the dialog visible until exec() gets called, unless you call QCoreApplication::processEvents() during the time consuming task. There is a little pitfall in this, though, because the dialog would end up being modeless during the time consuming task and turn to a modal dialog after the task is finished and exec() is called. This can be avoided by calling QDialog::setModal(true) before the time consuming task.
Code:
MyDialog d; // it's safe to allocate the dialog on the stack, because exec() blocks
mydialog.setModal(true);
mydialog.show();
for (...)
{
// do one part of the time consuming task
qApp->processEvents(); // let the app process it's events every once in a while
}
mydialog.exec(); // let the dialog start it's own event loop
Re: QDialog: show() and exec() together in constructor?
How about:
Code:
MyDialog d;
QTimer::singleShot(0,
&d,
SLOT(doTimeConsumingTask
()));
d.exec();
This should execute the slot immediately when d.exec() is called (provided that the event will not make it to a wrong queue). The drawback is that you will block the event loop if you do everything in the slot at once. So either do it the way J-P mentioned or split the task into subtasks, put each in a separate slot and as the last line of each slot start a timer that will trigger the next slot.
Re: QDialog: show() and exec() together in constructor?
Yes, I discovered this by trial and error :) Thanks anyway for your good explanation.
By the way, instead of using
Code:
qApp->processEvents();
I use
Code:
for(i=0; i<10; i++) qApp->processEvents();
because I have the impression that (specially under Windows) calling processEvents() only
one time isn't always enough when the OS is very busy (widgets aren't painted completely etc.).
Regards.
Re: QDialog: show() and exec() together in constructor?
processEvents() processes all events pending. The problem widgets are not painted is because you made the processor very busy. Instead use slots that'll get triggered every 100ms or so - the task will do its job slower, but the system stability will be sustained.
Re: QDialog: show() and exec() together in constructor?
I will use the solution with the QTimer, it gives better results than using qApp->processEvents();
Thanks for your help.