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)


  • Moderators

    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 call show() 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)


  • Moderators

    See the example in the QThread docs. The doWork() in the example is your lengthy operation and you could connect the close() slot of the message box to the resultReady() 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?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.