ChatGPT解决这个技术问题 Extra ChatGPT

Qt:如何处理用户按下“X”(关闭)按钮的事件?

在 Qt 中,对应于用户单击窗口框架的“X”(关闭)按钮的事件的插槽是什么,即这个按钮:

https://i.stack.imgur.com/rgFqm.png

如果没有这个插槽,在用户按下关闭按钮后,还有其他方法可以触发功能吗?


J
Jason Sundram

如果您有 QMainWindow,则可以覆盖 closeEvent 方法。

#include <QCloseEvent>
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();
    }
}


如果您将 QDialog 子类化,则不会调用 closeEvent,因此您必须覆盖 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();
    }
}

如果我的应用程序是通过子类化 QApplication 创建的,那么如何实现与上述相同的功能?
@pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp())); 应该可以工作。请参阅下面塞巴斯蒂安的回答。
您可能还想将 setAttribute(Qt::WA_QuitOnClose); 用于 MainWindow。
您确定子类化 QDialog 不会调用 closeEvent 吗?它对我有用,QCloseEvent 的文档说 事件处理程序 QWidget::closeEvent() 接收关闭事件 并且 QDialog 也是一个小部件,对吗?或者它是否与旧的 Qt 版本(<5.x)有关?
@incBrain 即使在 Qt 4.8 中,“X”按钮也会在 QDialog 中调用 closeEvent,但如果用户按下键盘上的 Esc,QDialog 会在不调用 closeEvent 的情况下关闭。
w
waldyrious

嗯,我明白了。一种方法是覆盖类定义中的 QWidget::closeEvent(QCloseEvent *event) 方法并将代码添加到该函数中。例子:

class foo : public QMainWindow
{
    Q_OBJECT
private:
    void closeEvent(QCloseEvent *bar);
    // ...
};


void foo::closeEvent(QCloseEvent *bar)
{
    // Do something
    bar->accept();
}

S
Sebastian Lange

您可以将 SLOT 附加到

void aboutToQuit();

QApplication 的信号。这个信号应该在应用程序关闭之前发出。


我们使用它的方式是:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
但是,quote from the documentation:“请注意,在此状态下无法进行任何用户交互。”
A
Alexander

你也可以重新实现受保护的成员 QWidget::closeEvent()

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