Search code examples
qtqobject

The timing to delete QObject using QObject::deleteLater()


Sample:

Test::Test(QWidget *parent)
{
    qDebug() <<"Test()";
}

Test::~Test()
{
    qDebug() <<"~Test()";
}

void MainWindow::slot_test()
{
    Test *p = new Test;
    // out Test() message here ok

    p->deleteLater();

    QCoreApplication::sendPostedEvents(0, 0);
    QCoreApplication::processEvents(QEventLoop::AllEvents);

    // no ~Test() message out here
    ....
}

I know that the implement of deleteLater is call
QCoreApplication::postEvent(this, new QDeferredDeleteEvent());

But why no "~Test()" message out when run after QCoreApplication::sendPostedEvents(0, 0) or run after QCoreApplication::processEvents(QEventLoop::AllEvents) ?

The above tow codes should dispatche all events in event queue, including QEvent::DeferredDelete?

The "~Test()" message appears when leave the function slot_test().

I think I don't understand the true meaning "The object will be deleted when control returns to the event loop" in the qt's document.

Could someone explain more clearly?


Solution

  • From the documentation for QCoreApplication::processEvents...

    In the event that you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed [My emphasis].

    If you change...

    QCoreApplication::sendPostedEvents(0, 0);
    QCoreApplication::processEvents(QEventLoop::AllEvents);
    

    to...

    QCoreApplication::instance()->exec();
    

    Then you should get the expected behaviour.

    (Note: I know that blocking your MainWindow::slot_test with a call to QCoreApplication::exec isn't a long term solution but... I'm guessing from its name -- slot_test -- that this is a Qt slot and will be invoked within the context of the main event loop anyway. In which case slot_test will return to that event loop and the DeferredDelete event processed there.)