Proper ask on close implementation



  • Hi,

    I am implementing a ask on close feature for my application. Atm this is done in the closeEvent function I have overridden in the mainwindow class. Relevant code is as follows:

    void MainWindow::closeEvent(QCloseEvent* event)
    {
        if (QMessageBox::No == QMessageBox::warning(this, 
                                                    qApp->applicationName(), 
                                                    "Are you sure you want to quit?",
                                                    QMessageBox::Yes, 
                                                    QMessageBox::No)) {
            event->ignore();
        } else {
            event->accept();
        }
    }
    

    My problem occurs during shutdown, most notably on windows platforms. Windows will not shutdown the application presumably because it is waiting on user input to confirm the quit. This is undesirable as I would like the application to properly shutdown if the operating system asks it to. Any advice as to how to solve this problem?

    Thanks in advance


  • Qt Champions 2016

    @CBPeckles said in Proper ask on close implementation:

    Windows will not shutdown the application presumably because it is waiting on user input to confirm the quit. This is undesirable as I would like the application to properly shutdown if the operating system asks it to. Any advice as to how to solve this problem?

    Do you mean in the case the OS sends SIGTERM to your application?



  • Yes, I believe in windows this signal would be WM_QueryEndSession.

    Just to clarify, the intended operation of the program would be

    • User clicks "X" in application bar -> confirm close
    • User clicks a button in the application connected to this->close -> confirm close
    • OS asks program to close -> do not confirm on close and exit program

  • Qt Champions 2016

    Then I suggest not running a local event loop. You'd do something like this:

    event->ignore();
    
    QCoreApplication * app = QCoreApplication::instance();
    
    QMessageBox * box = new QMessageBox(QMessageBox::Question, qApp->applicationName(), "Are you sure you want to quit?", QMessageBox::Yes | QMessageBox::No, this);
    
    QObject::connect(box->button(QMessageBox::Yes), &QAbstractButton::clicked, app, &QCoreApplication::quit);
    QObject::connect(box->button(QMessageBox::No), &QAbstractButton::clicked, box, &QObject::deleteLater);
    QObject::connect(app, &QCoreApplication::aboutToQuit, box, &QObject::deleteLater);
    


  • OK I think I understand.

    My problem was that the application was stuck in the QMessageBox's event loop and could not be shutdown, correct?

    Thank you for you help on this. It was much appreciated.


  • Qt Champions 2016

    @CBPeckles said in Proper ask on close implementation:

    My problem was that the application was stuck in the QMessageBox's event loop and could not be shutdown, correct?

    Yes, this is my theory. I might be wrong, but try the example snippet and if it works, I am right, if not post back here so we can start thinking of something else.



  • This appears to work as intended now. I believe you forgot a box.show() at the end of the code otherwise nothing happens. In case anyone sees this in the future, revised code, I believe, is as follows:

    void MainWindow::closeEvent(QCloseEvent* event)
    {
        event->ignore();
    
        QMessageBox* box = new QMessageBox(QMessageBox::Question, 
                                           qApp->applicationName(), 
                                           "Are you sure you want to quit?",
                                           QMessageBox::Yes | QMessageBox::No, 
                                           this);
    
        QObject::connect(box->button(QMessageBox::Yes), &QAbstractButton::clicked, qApp, &QApplication::quit);
        QObject::connect(box->button(QMessageBox::No), &QAbstractButton::clicked, box, &QObject::deleteLater);
        QObject::connect(qApp, &QApplication::aboutToQuit, box, &QObject::deleteLater);
        box->show();
    }
    

    Thanks again!


  • Qt Champions 2016

    @CBPeckles said in Proper ask on close implementation:

    I believe you forgot a box.show() at the end of the code

    Your belief is well founded, I did forgot it indeed.


Log in to reply
 

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