Understanding QMessagebox .exec() and .show()
-
Hi again!
I'm doing a QWizard with QT 4.8.5 and in some pages I have to close some other applications and exit my program. This works fine but now I want to show a pop up message that tells the user that the programs are restarting (There are others a part of mine and mine is the last one to be closed always). The code I use to show the pop up is the next one and I place it in the validatepage of a QWizardpage:
QMessageBox *msgBox1 = new QMessageBox; msgBox1->setWindowTitle("Title..."); msgBox1->setIcon(QMessageBox::Information); msgBox1->setText(" blablablalbal bla bla bla."); msgBox1->setWindowModality(Qt::NonModal); msgBox1->show(); QCoreApplication::processEvents(); // without this line, the show does nothing and I can't see my pop up window
So the thing is: With that code, When I am in that wizardpage and click to finish, it launches the QMessageBox while (behind) the program is restarting the other applications and then closes itself (with a QApplication::quit(); ) which is exactly what I want... BUT no message is shown in the pop up... I can't see the icon, the title or the text... :S I don't know why :(
Whereas when use ->exec(); instead of show, the icon, title and text are shown BUT when the pop up appears, nothing is done behind until the user closes that pop up... :S
I understand that .exec() freezes all until user closes the pop up while show doesn't...
So... how can I see the text with the show() behaviour?? I don't want the user to interact with that pop up, I just need the pop up to show up while closing all until my program closes too...
Thank you so much... (@kshegunov I bet you will see this and answer so double thank you for you before you do, maybe? :D)
-
You need to keep in mind how Qt "works". Everything happens in an event loop and that loop calls event handlers.
exec()
starts a new loop and does not return until you close the window.
show()
only shows the window. No loop is started so no events like painting are being processed. If you callshow()
and then immediately after do some lengthy operation you will basically freeze the ui until your operations finish. This is generally a bad idea and a terrible user experience, as you can't interact with the window and after a while, Windows at least, will show that your app is not responding.What you should™ do is start the lengthy operation in a separate thread, open the box with
exec()
to keep it responsive, and connect some signal at the end of your operation to the box close slot. -
@Chris-Kawa said:
you will basically freeze the ui
In that case it does't matter because my program is running in a specific HW of my enterprise and there is no mouse, just keyboard input and when the pop up appears users won't want to do anything but... yes, knowing that it freezes everything is a really bad idea and was not my intention...
What you should™ do is start the lengthy operation in a separate thread, open the box with exec() to keep it responsive, and connect some signal at the end of your operation to the box close slot.
I know I can use a thread with
thread = new QThread(); thread->start();
But I don't see how can I put the 'lengthy operation' into it... could you hel p me understand it a little bit please? Thank you!
connect some signal at the end of your operation to the box close slot.
Is there really a box close slot? I have not been able to find it ( at least the slot that should go here in that case) -
See the example in the QThread docs. The
doWork()
in the example is your lengthy operation and you could connect theclose()
slot of the message box to theresultReady()
signal. -
@Chris-Kawa said:
QThread docs
Oh!! Then I need to make a worker class and do something like:
thread = new QThread(); thread->start(); worker = new Worker; worker->moveToThread(thread); // this is the initialization of a QWizardPage in the QWizard WizardPageClass1 *page1 = new WizardPageClass1 ; page1->setWorker(worker);
And then where I have the lengthy operation, emit a signal (DoOperation for example) and in its constructor make a connect like
connect(this, DoOperation(), worker, doWork()) if doWork()
is where I have the lenghty operation with?