I have here a cut-down example of a crash indirect caused by setAttribute(Qt::WA_DeleteOnClose) and I do not know a nice way to prevent it.
To reproduce:
Compile that snipplet and start it. Then click into the window which shows up (it contains a pushbutton) and after that close the window (where you clicked into) by clicking on the bix X in the title line.
The crash happens because that attribute "Qt::WA_DeleteOnClose" calls the destructor of the main window. Since the small dialog has a parent, it is deleted too. Now it has its own exec() call where it loops.
Now I do not want to drop that "Qt::WA_DeleteOnClose" line, because this would mean unused memory which is still allocated and the application grows and grows ...
I also would like to show the child dialog centered above the main window and since I am lazy, is simple use the parent widget as a parameter during start.
I also would like to avoid a modal dialog.
If I could drop one of these three requirements, the crash would go.
One way could be to clear the parent of the child window. This would mean a lot of coding, since I need to know which child windows exists (there could be many, not just one), but as i wrote: I am lazy ...
Another way could be to drop the exec() call in the opened dialog, which would mean rearranging the logic in the caller, again this needs to handle a collection of a opened subdialogs ... I don't like that, since I am lazy.
Does anyone have another idea?
Qt Code:
#include <Qt/qapplication.h> #include <Qt/qpushbutton.h> #include <Qt/qmainwindow.h> #include <Qt/qdialog.h> #include <Qt/qlabel.h> #include <Qt/qlayout.h> #include <Qt/qevent.h> Q_OBJECT; public: SomeMainWin(); virtual ~SomeMainWin(); QPushButton *_openDialog; public slots: void openAnDialog(); }; public: virtual ~SomeDialog(); int run(); }; int main(int argc, char **argv) { SomeMainWin *myMainWin = new SomeMainWin(); myMainWin->show(); app.exec(); exit(0); } SomeMainWin::SomeMainWin() { setAttribute(Qt::WA_DeleteOnClose); connect(_openDialog, SIGNAL(clicked()), this, SLOT(openAnDialog())); setCentralWidget(_openDialog); } SomeMainWin::~SomeMainWin() { } { event->accept(); } void SomeMainWin::openAnDialog() { SomeDialog SomeDialog(this); // ... do this an that } } { setLayout(layout); layout->addWidget(label); } SomeDialog::~SomeDialog() { } int SomeDialog::run() { show(); exec(); } #include "main.moc"To copy to clipboard, switch view to plain text mode
the crash looks like this (it is Suse Linux)
$ ./a.out
QObject: Do not delete object, 'unnamed', during its event handler!
*** glibc detected *** ./a.out: double free or corruption (out): 0x00007fffc1a87630 ***
Bookmarks