Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to wait for 'deleteLater'?



  • I need to safely delete QWidget, but can not find a correct way to join into thread until widget is deleted.

    I tried following (which results in hang):

    @WId id = widget->winId();
    widget->deleteLater();
    while (QWidget::find(id))
    {
    qApp->sendPostedEvents(0, -1);
    qApp->processEvents();
    }@

    How can I do that?

    Thanks in advance, Dusan.
    Dusan



  • why not
    @ delete widget; @
    ?

    The whole point of deleteLater() is to schedule the deletion for the next event loop iteration, which by definition is outside your calling function here.



  • Shouldn't qApp->processEvents() process all pending events, including pending deleteLater() operations?

    If not, you could use QTimer::singleShot() with a short timeout value. This way, once the control returns to the event loop, it will first trigger the pending deleteLater() operation and then (after a short delay) call your timer-slot. Now you can be sure your slot-function is executed after the delete has actually been performed.

    But before you try sth. like this, you should ask yourself whether you can't get away with a simple delete...



  • [quote author="DerManu" date="1340734700"]why not
    @ delete widget; @
    ?

    The whole point of deleteLater() is to schedule the deletion for the next event loop iteration, which by definition is outside your calling function here.[/quote]

    In most cases delete widget; widget = NULL; works very well, but in case of QGLWidget, I am not sure why when I delete widget's parent, QApplication throws exception in its QFontCache cleanup (after delete qApp; I must delete qApp since I use QWinMigrate). On other side, if I use deleteLater, QApplication tries to process pending events and throws exception on widget's winEvent call, because found QWidget is invalid.

    So I need a way to correctly delete QWidget and be sure that it does not corrupt memory or something else that is causing those issues.



  • [quote author="MuldeR" date="1340744291"]Shouldn't qApp->processEvents() process all pending events, including pending deleteLater() operations?[/quote]

    Probably should, but as far as I can say, it does not :(

    [quote author="MuldeR" date="1340744291"]If not, you could use QTimer::singleShot() with a short timeout value. This way, once the control returns to the event loop, it will first trigger the pending deleteLater() operation and then (after a short delay) call your timer-slot. Now you can be sure your slot-function is executed after the delete has actually been performed.[/quote]

    This sounds good, but looks to be the same as 'deleted' event, so I would have to assign to events of widget before I delete it. Or could you please provide some pseudo code of how do you mean it?



  • Would it be an option to use the QObject::destroyed() signal?
    By the time that one is emitted, the widget parts of the object have already been destroyed.



  • [quote author="Andre" date="1340784921"]Would it be an option to use the QObject::destroyed() signal?
    By the time that one is emitted, the widget parts of the object have already been destroyed.[/quote]

    finally I found solution to wait for destroy:

    @widget->deleteLater();
    widget->exec();@

    unfortunately, delete qApp; still corrupts memory:

    Message:
    First-chance exception at 0x133a79b2 (QtGuid4.dll) in ustation.exe: 0xC0000005: Access violation reading location 0x0000000c.

    (Call stack:)
    @> QtGuid4.dll!qThreadStorage_deleteData<QFontCache>(void * d=0x141f4010, QFontCache * * __formal=0x00000000) Line 97 + 0x22 bytes C++
    QtGuid4.dll!QThreadStorage<QFontCache *>::deleteData(void * x=0x141f4010) Line 140 + 0xe bytes C++
    QtCored4.dll!QThreadStorageData::set(void * p=0x00000000) Line 165 + 0x7 bytes C++
    QtGuid4.dll!qThreadStorage_setLocalData<QFontCache>(QThreadStorageData & d={...}, QFontCache * * t=0x0028e35c) Line 92 + 0x12 bytes C++
    QtGuid4.dll!QThreadStorage<QFontCache *>::setLocalData(QFontCache * t=0x00000000) Line 155 + 0x14 bytes C++
    QtGuid4.dll!QFontCache::cleanup() Line 2804 C++
    QtGuid4.dll!QFont::cleanup() Line 111 C++@

    What could I try to find a source of this issue?
    I have put a breakpoint into QThreadStorageData::set() but it never gets called during Widget destruction, so I can not identify what is going wrong.

    Could you please suggest where to look (in QT source) to find source of this issue?

    Thanks.


Log in to reply