i have following use case (doesn't make sense, because it's minimized real-life working example, think it's still technically correct):
class dialog : public qdialog { public: dialog(qwidget* parent) : qdialog(parent) { new q3listview(this); // crash // new qwidget(this); // won't crash } }; depending on added dialog program crash or not when deleting dialog instance (as indicated comments in snippet), when main window's flags have been modified. here code mainwindow class, uses dialog:
class mainwindow : public qmainwindow { public: // fact widget (dialog) below // has no chance show seems irrelevant. // in real scenario have, widget shown on // screen , closed user. // i've put whole sequence of pieces of code // result signal/slot calls, in turn // result point&click scenario in our application // following function brevity. void go() { auto dialog = new dialog(this); dialog->show(); dialog->close(); disablealwaysontop(); delete dialog; // or dialog->deletelater(); } void disablealwaysontop() { setattribute(qt::wa_resized, true); qt::windowflags flags = windowflags(); setwindowflags(flags ^ (qt::customizewindowhint | qt::windowstaysontophint)); setvisible(true); } }; and implementation of main:
int main(int argc, char** argv) { qapplication app(argc, argv); mainwindow mainwindow; mainwindow.show(); mainwindow.go(); return app.exec(); } all lines seem essential reproduce crash.
is bug in qt, or doing wrong?
manually deleting widget's children allowed, , should automatically unregister parents indicated in quote manual below. in real-life case widget deleted disappear gui, , works in case of other widget combinations. indicated in comment above, changing delete dialog; dialog->deletelater(); doesn't help.
it seems there problem in removing q3listview instance qt's backing store, here stack trace:
qtguid4.dll!qwidgetbackingstore::staticcontents(qwidget * parent, const qrect & withincliprect) line 499 c++
qtguid4.dll!qwidgetbackingstore::sync() line 1200 c++
qtguid4.dll!qwidgetprivate::syncbackingstore() line 1896 c++
qtguid4.dll!qwidget::event(qevent * event) line 8694 c++
qtguid4.dll!qmainwindow::event(qevent * event) line 1479 c++
qtguid4.dll!qapplicationprivate::notify_helper(qobject * receiver, qevent * e) line 4565 c++
qtguid4.dll!qapplication::notify(qobject * receiver, qevent * e) line 4530 c++
qtcored4.dll!qcoreapplication::notifyinternal(qobject * receiver, qevent * event) line 955 c++
qtcored4.dll!qcoreapplication::sendevent(qobject * receiver, qevent * event) line 231 c++
qtcored4.dll!qcoreapplicationprivate::sendpostedevents(qobject * receiver, int event_type, qthreaddata * data) line 1579 c++
qtcored4.dll!qt_internal_proc(hwnd__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) line 498 c++
[external code]
qtcored4.dll!qeventdispatcherwin32::processevents(qflags flags) line 823 c++
qtguid4.dll!qguieventdispatcherwin32::processevents(qflags flags) line 1216 c++
qtcored4.dll!qeventloop::processevents(qflags flags) line 150 c++
qtcored4.dll!qeventloop::exec(qflags flags) line 204 c++
qtcored4.dll!qcoreapplication::exec() line 1227 c++
qtguid4.dll!qapplication::exec() line 3824 c++
qt_bug.exe!main(int argc, char * * argv) line 60 c++
and piece of qt's code attempts use pointer deleted object in line indicated in stack trace:
for (int = 0; < count; ++i) { qwidget *w = staticwidgets.at(i); qwidgetprivate *wd = w->d_func(); if (!wd->isopaque || !wd->extra || wd->extra->staticcontentssize.isempty() // **** || !w->isvisible() || (parent && !parent->isancestorof(w))) { continue; } (wd points deleted object @ line marked comment).
disclaimer: know more elegant solutions exist legacy code, , according qt's manual:
you can delete child objects yourself, , remove parents.
this code valid.
we've reproduced problem on windows 7 (msvc 2010 sp1, cl 16), windows 8 (msvc 2013 u4, cl 18) , fedora 20 (gcc 4.8.3).
i've filed bug report. since concerns old version of library no hopes fixed.
we successively removing qt3support anyway , advised ;)
Comments
Post a Comment