PDA

View Full Version : Qt::WA_DeleteOnClose while a child QDialog is executed



nooky59
10th July 2008, 17:47
Hi,

I have a QMainWindow subclass with the attribute Qt::WA_DeleteOnClose set.

In some cases, I open a QDialog (and more exactly QWizard) that is a child of QMainWindow.

If the user interact with a particular QAction from the systray icon, I close the QMainWindow subclass programatically. The problem is after the call to the QMainWindow destructor, the control flow returned right after the QWizard exec call :



if(wizard)
{
if(wizard->exec())
{
if(wizard->field("displayListing").toBool())
{
setRootIndex(listingIndex);
show();
}
}

delete wizard;
wizard = 0;
}


So in this particular case, delete wizard failed and I have a crash. Moreover, it is silly than some code class code could still be executed after the destruction of the object !!!

I have a solution (hope it could help) but I would like to know if there is a better way to deal with it.

Here is my solution by overidding the close() slot of the QMainWindow :



void MyWindow::close()
{
if(wizard)
{
closeRequested = true;
wizard->reject();
}
else
{
QMainWindow::close();
}
}


So if the wizard pointer is not null, i set a member boolean variable to true and I programatically reject the dialog rather than propagating the close() call to the parent (QMainWindow) classe.

Then, the control returned right after the wizard->exec() call, I can safely destroy it and it test the boolean just after and do my close() call then.

Do you think there is a much cleaner solution ?

jpn
10th July 2008, 18:17
How about something like:

connect(window, SIGNAL(destroyed()), wizard, SLOT(reject()));
or just call QApplication::quit() in the first place?

nooky59
11th July 2008, 10:19
How about something like:

connect(window, SIGNAL(destroyed()), wizard, SLOT(reject()));
or just call QApplication::quit() in the first place?

Good idea, I didn't tried this way (but I have tried to call reject() on the wizard directly from my destructor but it was not working) but it did not work as well.

Curiously I've got this error in the debug output :

QObject: Do not delete object, 'qt_scrollarea_viewport', during its event handler!

I have a QScrollArea in my mainwindow but if the wizard is not executed, the destruction process is ok so I really don't think this error is related to the qt_scrollarea_viewport of my main window.

Perhaps the fact that a QDialog is modal when called with exec() is blocking the event loop of the main window and that it is not really good to destroy the object while the event loop is in this state so not properly destroyed ?

Anyway, as I told in my first post, I've got a solution, i was just looking for a potential better one ;o)

jpn
11th July 2008, 11:52
Curiously I've got this error in the debug output :

QObject: Do not delete object, 'qt_scrollarea_viewport', during its event handler!
Use QObject::deleteLater() instead of C++ delete operator.

nooky59
11th July 2008, 12:45
Use QObject::deleteLater() instead of C++ delete operator.

The problem is the delete is triggered automatically by the close() operation as Qt::WA_DeleteOnClose is set.