Qt析构函数调用已关闭的小部件

axe*_*axe 8 c++ qt destructor memory-management

有应用程序来处理文本命令.我有一个用一些close *命令关闭的Qt小部件.Qt::WA_DeleteOnClose为该窗口小部件设置了属性,它接收closeEvent,但稍后会调用该对象的析构函数(我猜在空闲时).如果我有两个命令 close *; get something;,程序崩溃,因为get something在该小部件的析构函数之前调用,因此它尝试访问由close *命令删除的数据.我如何强迫Qt调用析构函数?QCoreApplication::processEvents()关闭命令后没有帮助.将qt版本从4.3.3更改为4.7.2后,我遇到了这个问题.这里没有多线程.

提前致谢.

添加

这是代码示例.

test *t = new test();
t->show();
std::cout << "before deleteLater()" << std::endl;
t->deleteLater();
std::cout << "after deleteLater()" << std::endl;
QCoreApplication::sendPostedEvents();
QCoreApplication::processEvents();
std::cout << "after processEvents()" << std::endl;
Run Code Online (Sandbox Code Playgroud)

测试类派生自QDialog.它test()在构造函数和~test()析构函数中打印.此代码提供以下输出

test()
before deleteLater()
after deleteLater()
after processEvents()
~test()
Run Code Online (Sandbox Code Playgroud)

根据Qt文档,它应该在最后一个cout之前删除该对象,我是对的吗?看起来像Qt中的一个错误,有人知道吗?任何解决方法?

我在Qt邮件列表中问了这个问题,但仍在等待答案.

谢谢.

还有一次更新

这段代码

Dialog::~Dialog() {
    std::cout << "~test()" << std::endl;
}

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    Dialog* dlg = new Dialog();
    dlg->setAttribute(Qt::WA_DeleteOnClose);
    dlg->show();
    dlg->close();
    std::cout << "before sendPostedEvents()" << std::endl;
    QCoreApplication::sendPostedEvents();
    std::cout << "after sendPostedEvents()" << std::endl;
    return app.exec();
}
Run Code Online (Sandbox Code Playgroud)

打印这个

before sendPostedEvents()
after sendPostedEvents()
~test()
Run Code Online (Sandbox Code Playgroud)

但是一旦我添加了closeEvent处理程序并在该处理函数中调用deleteLater(),sendPostedEvents就会开始删除延迟对象.

void Dialog::closeEvent(QCloseEvent* ev) {
    deleteLater();
    QWidget::closeEvent(ev);
}
Run Code Online (Sandbox Code Playgroud)

在sendPostedEvents()之后在sendPostedEvents()~test()之前打印这个

谁能解释那里到底发生了什么?这只是一个错误吗?我可以将其用作解决方法吗?

这是如何运作的?如果设置了CloseOnDelete属性,那么在接受closeEvent后,Qt是否应自动调用deleteLater()?

use*_*ged 7

设置Qt::WA_DeleteOnClose意味着qt可以在你打电话后随时删除,close()因为qt在deleteLater()内部使用.您可以使用QObject::destroyed()信号确保删除.