wa
今天在解决软件bug的过程中,注意到QT关于[slot] bool QWidget::close()
有这样一段说明:
If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. A close events is delivered to the widget no matter if the widget is visible or not.
逆向思考,如果我的QWidget或继承于QWidget的派生类没有设置相关的flag:Qt::WA_DeleteOnClose
,那么他是不会自动析构的。情况真是如此吗?
测试环境:
macOS Mojave 10.14
Qt Creator 4.41
Qt 5.9.2
Clang 7.0 APPle, 64 bits
场景一: 独立widget,没有flag Qt::WA_DeleteOnClose
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
qDebug() << "Widget::~Widget()";
}
void Widget::on_pushButton_clicked()
{
close(); //output: Widget::~Widget()
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.ui:
在这种情况下,不设置flag QT::WA_DeleteOnClose
,我们依然可用通过函数链:Widget::on_pushButton_clicked
=> Widget::close
来触发析构函数。
那么QT关于此flag的说明到底是什么意思呢?接着看下面的场景。
场景二: 自定义的widget作为其他widget的child widget,没有flag Qt::WA_DeleteOnClose
现在widget.ui文件设置成这样:
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget parentW;
parentW.show();
Widget w(&parentW);
w.show();
setbuf( stdout, NULL );
return a.exec();
}
qwidget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
printf( "this: %p\n", this );
printf( "ui: %p\n", ui );
}
Widget::~Widget()
{
delete ui;
qDebug() << "Widget::~Widget()";
}
void Widget::on_pushButton_clicked()
{
qDebug() << testAttribute( Qt::WA_DeleteOnClose );
close();
}
一开始显示:
然后我们点击button,button消失。输出:
this: 0x7ffeed17e9e0
ui: 0x7faaacd12c40
false
析构函数没有被调用。
场景三: 自定义的widget作为其他widget的child widget,有flag Qt::WA_DeleteOnClose
在场景二的基础上,Widget的构造函数中加上:
setAttribute( Qt::WA_DeleteOnClose, true );
运行,再点击button,我们得到:
this: 0x7ffee5578a28
ui: 0x7fc99ef14f70
true
Widget::~Widget()
The program has unexpectedly finished.
The process was ended forcefully.
系统报错:ERROR for object 0x7ffee5578a28: pointer being freed was not allocated
也就说,函数链:Widget::on_pushButton_clicked
=> Widget::close
触发了一次析构函数,后面widget的对象又被析构了一次。
注意到我们的Widget对象在main.cpp中是分配到栈内存的,所以在main函数结束后,系统会尝试析构我们的Widget对象。
在qwidget.cpp我们能找到这样的语句:
8442 if (!that.isNull()) {
8443 data.is_closing = 0;
8444 if (q->testAttribute(Qt::WA_DeleteOnClose)) {
8445 q->setAttribute(Qt::WA_DeleteOnClose, false);
8446 q->deleteLater();
8447 }
8448 }
8449 return true;
8450 }
接着,将Widget对象从堆里申请内存,就不会存在多次释放内存的问题了。
main.cpp
Widget *w = new Widget(&parentW);
w->show();
点击红色的button之后:
总结:Qt::WA_DeleteOnClose用于申请堆内存的QWidget对象,并有通过close方法释放内存的需求的场景。相关阅读
最近,经常在一些论坛看到QT刷单兼职,QT兼职刷信誉,网上兼职QT等字眼。那么,这些兼职是真的吗,这些兼职具体而言是什么?今天我们来了
在文件最后添加:greeter-show-manual-login=true,保存并退出注销后重新登录,选择“login”,输入用户名:root,密码就是刚才在sudo passwd
某网站号称全网最低价一百块出售的奇迹私服发布站程序 适合有基础的兄弟拿 关于这个发布站程序 当时购买回来发现BUG还挺多的,上手
对于喜欢看电影的伙伴来说,优惠券可是深深吸引着他们,每当有新电影出来,大家就可以使用淘票票优惠券来省下一点钱哦,今天就给大家分享
如何使用Excel的Open事件及MsgBox函数制作提示对话框
对于某些具有特殊功能的Excel表格,有时需要在打开Excel工作表时能够出现提示对话框,对表格的功能、操作以及制作的有关信息等进行说