相关文章推荐
率性的啤酒  ·  ::-webkit-scrollbar - ...·  1 年前    · 
俊秀的乌冬面  ·  Cause: ...·  1 年前    · 
温柔的鞭炮  ·  【OpenCV Error】 ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

In Qt, what is the slot that corresponds to the event of the user clicking the 'X' (close) button of the window frame i.e. this button:

If there isn't a slot for this, is there any other way to trigger a function after the user presses the close button?

void MainWindow::closeEvent (QCloseEvent *event) QMessageBox::StandardButton resBtn = QMessageBox::question( this, APP_NAME, tr("Are you sure?\n"), QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes); if (resBtn != QMessageBox::Yes) { event->ignore(); } else { event->accept();


If you're subclassing a QDialog , the closeEvent will not be called and so you have to override reject() :

void MyDialog::reject()
    QMessageBox::StandardButton resBtn = QMessageBox::Yes;
    if (changes) {
        resBtn = QMessageBox::question( this, APP_NAME,
                                        tr("Are you sure?\n"),
                                        QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
                                        QMessageBox::Yes);
    if (resBtn == QMessageBox::Yes) {
        QDialog::reject();
                Are you sure that subclassing QDialog will not call closeEvent? It works for me, and the documentation of QCloseEvent says that The event handler QWidget::closeEvent() receives close events and QDialog is also a Widget right? Or is it related to older Qt version (<5.x) somehow?
– Dimitri Podborski
                Mar 30, 2016 at 10:17
                @incBrain Even in Qt 4.8 the 'X' button calls closeEvent in a QDialog, but if the user press Esc on the keyboard the QDialog is closed without calling closeEvent.
– asclepix
                Mar 31, 2016 at 9:57
                @asclepix thanks for clarification. So basically overwriting reject function would be the right move to solve this problem. I've found this sentence in the documentation: In order to modify your dialog's close behavior, you can reimplement the functions accept(), reject() or done(). The closeEvent() function should only be reimplemented to preserve the dialog's position or to override the standard close or reject behavior
– Dimitri Podborski
                Mar 31, 2016 at 10:25

Well, I got it. One way is to override the QWidget::closeEvent(QCloseEvent *event) method in your class definition and add your code into that function. Example:

class foo : public QMainWindow
    Q_OBJECT
private:
    void closeEvent(QCloseEvent *bar);
    // ...
void foo::closeEvent(QCloseEvent *bar)
    // Do something
    bar->accept();
                However, quote from the documentation: "Note that no user interaction is possible in this state."
– Ignitor
                Dec 7, 2015 at 11:02
                It works for me, but note that unlike reimplementing QMainWindow::closeEvent(), you cannot cancel application closing.
– Valentin Safonnikov
                Aug 25, 2022 at 6:40

also you can reimplement protected member QWidget::closeEvent()

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);

To capture the event of the close button being pressed without deriving from QWidget and the sort, you could use an event filter.

Here's a simple demonstration, using a simple application that displays a QWidget:

If you use QWidget itself, you need to capture QEvent::Close:

#include "myEventFilter.h"
#include <QApplication>
#include <QWidget>
int main(int argc,char*argv[])
    QApplication a(argc, argv);
    w.installEventFilter(filter);
    QWidget *w = new QWidget();
    //install the event filter on the widget
    w->installEventFilter(filter);
    w->show();
    return a.exec();

Event filter:

#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H
#include <QObject>
#include <QDebug>
#include <QEvent>
class myEventFilter : public QObject
    Q_OBJECT
public:
    myEventFilter (QObject *parent = nullptr) {}
protected:
    bool eventFilter(QObject * obj, QEvent * event) override
        if (event->type() == QEvent::Close)
            //handle the event here
            qDebug()<<"out";
           //In case you need the QWidget itself 
           QWidget *w = static_cast<QWidget*>(obj);
        return QObject::eventFilter(obj, event);
#endif // MYEVENTFILTER_H

If you use QApplication's object, you need to capture QEvent::Quit:

#include <QApplication>
#include "myEventFilter.h"
int main(int argc,char*argv[])
    QApplication a(argc, argv);
    QWidget *w = new QWidget();
    myEventFilter *filter = new myEventFilter();
    //install the event filter on QApplication object
    a.installEventFilter(filter);
    w->show();
    return a.exec();

Event filter

#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H
#include <QObject>
#include <QDebug>
#include <QEvent>
#include <QLineEdit>
class myEventFilter : public QObject
    Q_OBJECT
public:
    myEventFilter (QObject *parent = nullptr) {}
protected:
    bool eventFilter(QObject * obj, QEvent * event) override
        if (event->type() == QEvent::Quit)
            //handle the event here as well
            qDebug()<<"out";
        return QObject::eventFilter(obj, event);
#endif // MYEVENTFILTER_H
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.