> 文章列表 > 【QT】详细介绍Qt的窗口属性:Qt::WA_DeleteOnClose属性

【QT】详细介绍Qt的窗口属性:Qt::WA_DeleteOnClose属性

【QT】详细介绍Qt的窗口属性:Qt::WA_DeleteOnClose属性

目录

  • 1. close()
  • 2. WA_DeleteOnClose属性
  • 3. 测试
    • 3.1 设置了 Qt::WA_DeleteOnClose 属性
    • 3.2 未设置 Qt::WA_DeleteOnClose 属性
  • 4. 测试代码

1. close()

当我们创建一个窗口(MainWindow, Widget, Dialog, QMessageBox, 等等)后,我们一般会调用close()方法来关闭窗口。

//关闭这个小部件。如果小部件被关闭,则返回true; 否则返回false。
bool QWidget::close() 

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

2. WA_DeleteOnClose属性

//设置销毁窗口的属性
setAttribute(Qt::WA_DeleteOnClose);

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

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

3. 测试

下面是做一个小测试,通过不断打开窗口,再关闭所有打开的窗口。在任务管理器中对比该应用程序所占用的资源大小。

3.1 设置了 Qt::WA_DeleteOnClose 属性

【QT】详细介绍Qt的窗口属性:Qt::WA_DeleteOnClose属性

3.2 未设置 Qt::WA_DeleteOnClose 属性

【QT】详细介绍Qt的窗口属性:Qt::WA_DeleteOnClose属性

4. 测试代码

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QHBoxLayout>
#include <QMainWindow>
#include <QMessageBox>
#include <QPushButton>
#include <QVBoxLayout>namespace Ui {class MainWindow;
}class MainWindow : public QMainWindow {Q_OBJECTpublic:explicit MainWindow(QWidget* parent = 0);~MainWindow();private slots:void slotBtnClicked();private:Ui::MainWindow* ui;
};#endif  // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);resize(600, 400);QWidget* widget = centralWidget();QHBoxLayout* HLayout = new QHBoxLayout();QPushButton* btn = new QPushButton(widget);btn->setText(QStringLiteral("打开窗口"));HLayout->addStretch(3);HLayout->addWidget(btn, Qt::AlignHCenter);HLayout->addStretch(3);QVBoxLayout* VLayout = new QVBoxLayout(widget);VLayout->addLayout(HLayout);VLayout->addStretch(1);connect(btn, &QPushButton::clicked, this, &MainWindow::slotBtnClicked);
}MainWindow::~MainWindow() { delete ui; }void MainWindow::slotBtnClicked() {static int i = 1;QMessageBox* mesBox = new QMessageBox(this);mesBox->setAttribute(Qt::WA_DeleteOnClose);  //设置属性mesBox->setWindowTitle(QStringLiteral("提示"));mesBox->setText(QStringLiteral("您打开了%1个窗口").arg(i++));mesBox->setModal(false);  //设置非模态mesBox->setVisible(true);
}