开发者

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);

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜