有应用程序处理文本命令。我有一个用一些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;
测试类派生自QDialog。它在构造函数中打印test()
,在析构函数中打印~test()
。此代码提供以下输出
test()
before deleteLater()
after deleteLater()
after processEvents()
~test()
根据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();
}
打印此
before sendPostedEvents()
after sendPostedEvents()
~test()
但是只要我在该处理程序函数中添加了closeEvent处理程序并调用deleteLater(),sendPostedEvents就会开始删除延迟对象。
void Dialog::closeEvent(QCloseEvent* ev) {
deleteLater();
QWidget::closeEvent(ev);
}
打印出来 在sendPostedEvents()之前 〜测试() 在sendPostedEvents()之后
有人可以解释那里到底发生了什么吗?这只是一个错误吗?我可以将其用作解决方法吗?
这是如何工作的?如果设置了CloseOnDelete属性,那么在接受closeEvent后,Qt是否应自动调用deleteLater()?
答案 0 :(得分:7)
设置Qt::WA_DeleteOnClose
表示qt可以在您致电close()
后随时删除,因为qt在内部使用deleteLater()
。您可以使用QObject::destroyed()
信号确保删除。
答案 1 :(得分:1)
QCoreApplication :: processEvents在关闭事件时显式跳过删除。您需要将QEventLoop :: DeferredDeletion传递给processEvents()。即QCoreApplication :: processEvents(QEventLoop :: DeferredDeletion);