Nguyen Huu Tuyen
Nguyen Huu Tuyen

Reputation: 165

How to detect that the close button of QWidget is pressed?

I create a new QWidget object and I want to know when the close button is pressed.

I have tried the following code:

pWindow = new QWidget();
connect(pWindow , SIGNAL(triggered()), this, SLOT(processCloseButtonWindowsClicked()));

but it give an error:

no signal triggered of pWindow

How to achieve this?

Upvotes: 11

Views: 14233

Answers (3)

Atom94
Atom94

Reputation: 31

Before, check if Qt has a class for what you want to do. Maybe you want to use QDialog instead of QWidget for what you want to achieve.

The following code: suppose you want to delete the widget when the X is clicked and you just want to know when to do something. Try connecting the signal from the base class QObject of your widget when it is Destroyed:

-Your Widget

-attribute setted to destroy your widget after X(closebotton is clicked) or the close() handler is triggered

-connect the destroyed() signal to whatever slot you want to do something before it is destroyed

pWindow = new QWidget();
pWindow->setAttribute(Qt::WA_DeleteOnClose,true);
connect(pWindow , SIGNAL(destroyed()), this,SLOT(processCloseButtonWindowsClicked()));

for more info:

https://doc.qt.io/qt-5/qwidget.html#close

https://doc.qt.io/qt-5/qobject.html#destroyed

Upvotes: 1

scopchanov
scopchanov

Reputation: 8429

Cause

QWidget does not have a triggered signal.

Solution

I would suggest you to:

  1. Subclass QWidget and reimplement QWidget::closeEvent

  2. Check QEvent::spontaneous to differentiate between a click of the close button and the call to QWidget::close

  3. According to your app's logic either call QWidget::closeEvent(event); to close the widget, or QEvent::ignore to leave it open

Example

I have prepared an example for you of how to implement the proposed solution:

#include <QMainWindow>
#include <QCloseEvent>
#include <QPushButton>

class FooWidget : public QWidget
{
    Q_OBJECT
public:
    explicit FooWidget(QWidget *parent = nullptr) :
        QWidget(parent) {
        auto *button = new QPushButton(tr("Close"), this);
        connect(button, &QPushButton::clicked, this, &FooWidget::close);
        resize(300, 200);
        setWindowTitle("Foo");
    }

protected:
    void closeEvent(QCloseEvent *event) override {

        if (event->spontaneous()) {
            qDebug("The close button was clicked");
            // do event->ignore();
            // or QWidget::closeEvent(event);
        } else {
            QWidget::closeEvent(event);
        }
    }
};

class MainWindow : public QMainWindow
{
    Q_OBJECT
    FooWidget *pWindow;
public:
    explicit MainWindow(QWidget *parent = nullptr) :
        QMainWindow(parent),
        pWindow(new FooWidget()) {
        pWindow->show();
    }
};

Upvotes: 14

umairEravur
umairEravur

Reputation: 21

void QWidget::closeEvent(QCloseEvent *event) will be the possible way I would go with.

You can read the documentation here.

Upvotes: -1

Related Questions