Qt关于窗口关闭触发函数/信号

本文介绍了Qt中窗口关闭时如何触发相应函数或信号。点击窗口右上角的X键会触发QCloseEvent,可通过重写closeEvent()函数进行自定义处理。调用accept()关闭窗口,ignore()则阻止关闭。使用全局指针qApp->quit()可退出整个应用程序。另外,设置Qt::WA_DeleteOnClose标志会触发destroy信号,用于销毁资源。

方法一、

窗口右上角的X按键会导致其在不给出任何提示的情况下直接退出,
当点击右上角的x按键时,会触发Qt中的一个事件处理函数:void QWidget::closeEvent ( QCloseEvent * e ),默认情况该函数无任何提示性消息,如果需提示则需要重写该函数

void Dialog::closeEvent ( QCloseEvent * e )
{
    if( QMessageBox::question(this,
                             tr("Quit"),
                             tr("Are you sure to quit this application?"),
                              QMessageBox::Yes, QMessageBox::No )
                   == QMessageBox::Yes){
        e->accept();//不会将事件传递给组件的父组件

        qDebug()<<"ok";
    }
    else
      e->ignore();  
}

说明:

  • 事件的ignore函数表示忽略事件,将其传到父组件进行处理
  • 事件的accept函数表示接受事件,组件自己进行处理,不会将事件传递给父组件
  • 但是在这个closeEvent函数中,这两个函数尤其不一样的理解:对于窗口关闭QCloseEvent事件,调用accept()意味着 Qt 会停止事件的传播,窗口关闭;调用ignore()则意味着事件继续传播,即阻止窗口关闭。

此外如果需要直接退出某个应用程序,可以直接调用Qt中的一个全局指针:qApp ,全局指针qApp指向全局的QApplication对象。

//在需要停止程序运行的位置直接加入如下代码
#include <QtGui/QApplication>
...
  qApp->quit();

说明:

  • qApp是一个全局的函数,可以在Qt说明文档中直接找到,不是main函数定义的QApplication对象(QApplication对象也可以退出,使用 app->exit(0);或者 app->quit();具体可以参考【1】)
  • qApp->quit()关闭的是整个应用程序,不只是窗口,
  • 一般情况下关闭窗口应用程序会直接退出,如果要求关闭窗口时,应用程序不退出,则需要设置QApplication的属性:
QApplication::setQuitOnLastWindowClosed(false);

方法二、

QWidget的close槽函数是像widget发送QCloseEvent,如果widget未设置Qt::WA_DeleteOnClose标志的话,将隐藏widget,并不会销毁相关资源。如果设置了该标志,那么会再发送destroy信号,销毁相关资源。

(多说一句:QWindow的close槽是调用destroy来销毁窗口资源的。不过我们一般不直接使用QWindow。)

Qt帮助文档中的介绍:

调用close()方法后首先它会向widget发送一个关闭事件(QCloseEvent)。如果widget接受了关闭事件(QCloseEvent),窗口将会隐藏(实际上调用hide())。
如果widget不接受关闭事件,那么窗口将什么也不做。默认情况下widget会接受关闭事件,我们可以重写QCloseEvent事件,可以选择接受或者不接受。

如果widget设置了Qt::WA_DeleteOnClose属性,widget将会被释放。不管widget是否可见,关闭事件都会传递给widget。即接收到QCloseEvent事件后,
除了调用hide()方法将窗口隐藏,同时会调用deleteLater()方法将窗口释放掉,不会再占用资源。

所以说调用close()并不一定就会将窗口对象销毁。而只有设置了 Qt::WA_DeleteOnClose属性才会删除销毁。如果这个属性没有设置,close()的作用和hide(),
setvisible(false)一样,只会隐藏窗口对象而已,并不会销毁该对象。

这样的话我们可以给QLabel(拿它当一个例子)设置Qt::WA_DeleteOnClose

QLabel *label = new QLabel;
label->setAttribute(Qt::WA_DeleteOnClose);

之后用connect使用label的destroyed信号绑定一个槽函数即可

connect(label, &QLabel::destroyed, this, [=]() {
    QString file_path = QFileDialog::getSaveFileName(this, "save file", "tmp.png", "(*.png);;all files(*.*)");
        if(!file_path.isEmpty())
        ......
});

原文链接:Qt关于窗口关闭触发函数/信号-Qt开发中文网

### Qt窗口关闭触发信号Qt框架内,当用户尝试关闭一个窗口时,会触发特定的事件和信号来通知应用程序。对于顶级窗口而言,`QCloseEvent` 是主要用来处理此类情况的机制之一[^2]。 #### 处理 `QCloseEvent` 为了响应用户的关闭请求,在自定义窗口类中重载虚函数 `closeEvent(QCloseEvent*)` 可以捕获到即将发生的关闭动作,并允许开发者在此处加入额外逻辑,比如询问用户是否真的要退出应用: ```cpp void MyMainWindow::closeEvent(QCloseEvent *event) { QMessageBox::StandardButton resBtn = QMessageBox::question( this, "App Name", tr("Are you sure?\n"), QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes); if (resBtn != QMessageBox::Yes) { event->ignore(); } else { event->accept(); } } ``` 上述代码展示了如何通过对话框向用户提供选项,决定是否继续关闭过程。 #### 应用程序级别的信号 除了单个窗口层面外,整个应用程序也可以监听最后一个顶层窗口关闭的情况。一旦所有其他可见的顶级窗口都已关闭,则发出 `QGuiApplication::lastWindowClosed()` 信号[^3]。此功能有助于确保即使存在多个独立运行的窗口实例,也能适当地管理整体的应用生命周期。 #### 动态连接与断开信号 有时可能希望有条件地启用或禁用某些组件上的信号发射行为。为此目的,可以通过调用对象的方法如 `blockSignals(bool)` 来暂时阻止发送指定类型的信号;或者利用更细粒度的方式——即直接操作内部状态变量来影响何时应该激活这些回调链路[^4]。 #### 使用销毁信号 另外一种方法涉及监控具体部件的生命期结束时刻。例如,如果想要在一个标签(`QLabel`) 被删除之前保存其内容至文件系统中,那么可以考虑将其自身的 `destroyed(QObject *)` 信号关联到合适的槽函数上去完成这项工作[^5]: ```cpp connect(label, &QLabel::destroyed, this, [=]() { QString file_path = QFileDialog::getSaveFileName(this, "save file", "tmp.png", "PNG Files (*.png);;All Files (*)"); if (!file_path.isEmpty()) // 执行保存操作... }); ``` 以上几种方式共同构成了Qt环境下灵活而强大的事件驱动编程模型的一部分,使得开发人员能够有效地管理和回应各种UI交互场景下的需求变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值