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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.