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.