QMainWindow close() signal not emitted

12,281

In your mainwindow class header( the closeEvent must be virtual ):

public:
    /*!
     * \brief closeEvent
     * \param event
     */
    virtual void closeEvent ( QCloseEvent * event );

Then in the cpp

void MainWindow::closeEvent( QCloseEvent *event )
{
    //! Ignore the event by default.. otherwise the window will be closed always.
    event->ignore();

    if(!EntitiesSaverObserver::Instance()->isAllSaved())
    {
        QMessageBox msgBox;
        msgBox.setWindowIcon(QIcon(":/Resources/Icons/warning.png"));
        msgBox.setIconPixmap(QPixmap(":/Resources/Icons/warning.png"));
        QString strToShow = QString("Some Entities has been created or modified...");
        msgBox.setText(strToShow);
        msgBox.setInformativeText("Do you want to save your changes?");
        msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Save);
        int ret = msgBox.exec();

        switch (ret) {
          case QMessageBox::Save:
            {
              // Save was clicked
              qDebug() << "SAVE";
              //! Do your stuff here
              // ....
              event->accept();
              break;
            }
          case QMessageBox::Discard:
            {
                // Don't Save was clicked
                qDebug() << "DISCARD";
                event->accept();
                break;
            }
          case QMessageBox::Cancel:
            {
              // Cancel was clicked
              qDebug() << "CANCEL";
              break;
            }
          default:
              // should never be reached
              break;
        }
    } else {
        event->accept(); // Do not need to save nothing... accept the event and close the app
    }
}

Moreover, if you want to put a button in your toolbar as a QAction, you could connect the signal and then:

void MainWindow::on_actionExit_triggered()
{
    close();
}

This would call the close event of your main window. I hope this helps you.

Share:
12,281
Admin
Author by

Admin

Updated on June 13, 2022

Comments

  • Admin
    Admin almost 2 years

    To warn before closing a window that inherits from QMainWindow, I reimplemented its closeEvent, which works fine when I emit close() manually. However, clicking the "x" button does not trigger this; it just exits.

    It does emit aboutToQuit() for the application, which I can use to "recover" the window after it already closes. But I want to the warning to precede the initial closing.

    I'm not sure where the issue is. The window is top-level and there are no running threads. Have I misunderstood what signal is actually connected to the button click...? It is close(), right?

  • haris
    haris almost 9 years
    Not enough reputation to comment
  • Ruud van Gaal
    Ruud van Gaal over 7 years
    This is the inverse; making a button close the window. The OP asked how to get in front of the close() operation, not a way to execute close().