Qt destructor call for closed widget
There is application that handles text commands. I have a Qt widget that is closed with some close *
command. Qt::WA_DeleteOnClose
attribute is set for that widget, it receives closeEvent, but destructor for that object is called later (I guess on idle). If I have two commands
close *; get something;
the program crashes because get something
is called before destructor for that widget, so it tries to access data deleted by close *
command. How can I force Qt to call destructors? QCoreApplication::processEvents()
after close command doesn't help.
I've got this problem after changing qt version to 4.7.2 from 4.3.3. There is no multithreading here.
Thanks in advance.
开发者_如何学运维added
Here is the code example.
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;
test class is derived from QDialog. It prints test()
in constructor and ~test()
in destructor. This code gives the following output
test()
before deleteLater()
after deleteLater()
after processEvents()
~test()
According to Qt documentation it should delete the object before last cout, am I right? Looks like a bug in Qt, does anybody know anything about it? Any workaround?
I asked the question in Qt mailing list, but still waiting for an answer.
Thanks.
one more update
This code
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();
}
prints this
before sendPostedEvents()
after sendPostedEvents()
~test()
but as soon as I add closeEvent handler and call deleteLater() in that handler function sendPostedEvents starts deleting deferred objects.
void Dialog::closeEvent(QCloseEvent* ev) {
deleteLater();
QWidget::closeEvent(ev);
}
prints this before sendPostedEvents() ~test() after sendPostedEvents()
Can anybody explain what the hell is going on there? Is it just a bug? Can I use that as a workaround?
How does this work? Shouldn't Qt call deleteLater() automatically, after closeEvent is accepted if CloseOnDelete attribute is set?
Setting Qt::WA_DeleteOnClose
means qt can delete anytime after you call close()
because qt uses deleteLater()
internally. You can ensure the deletion using QObject::destroyed()
signal.
QCoreApplication::processEvents explicitly skips delete on close events. You need to pass QEventLoop::DeferredDeletion to processEvents(). i.e. QCoreApplication::processEvents(QEventLoop::DeferredDeletion);
精彩评论