WA_DeleteOnClose and exec()
I have created a child class of QDialog (NDialog). This class has WA_DeleteOnClose set up in its constructor. This is done because the parent of these dialogs persists for the duration of the entire program and there may be countless dialogs throughout the course of the program, so I'd rather not wait for the end of the program, and thus the destruction of the parent, to destroy all the countless dialogs at once. So I thought it better to simply set WA_DeleteOnClose on each dialog so that, once OK, Cancel or whatnot is pressed, the dialog gets deleted.
This works just fine, as far as I can tell.
However, the class has a static method Error which displays a modal (all others are modeless) dialog with the given error message. In this case, and this case only, WA_DeleteOnClose causes a crash. If I remove this attribute, the error dialog closes just fine, but theoretically won't be deleted until the end of the program.
Should it help, here's the relevant code:
Code:
{
Q_OBJECT
public:
{
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(title);
setLayout(&Layout);
};
void AddWidget
(QWidget* widget
) //add a widget to the layout {
Layout.addWidget(widget);
};
static void Error
(QString value
) //diplays error message {
NDialog* dlg = new NDialog("ERROR");
dlg->setAttribute(Qt::WA_DeleteOnClose,false);
dlg->AddWidget(&msg);
connect(&ok,SIGNAL(clicked()),dlg,SLOT(close()));
dlg->AddWidget(&ok);
dlg->exec();
};
};
This is the case where the code works. If I remove the "dlg->setAttribute(Qt::WA_DeleteOnClose,false);" line, the program crashes.
This is the only time I use dlg->exec() as opposed to dlg->show(). Does this have anything to do with it?
Re: WA_DeleteOnClose and exec()
Not sure of the crash, as you have not mentioned when the program crashes, or at least the stack trace.
Anyways following is a better, and good way to do. I recommend it this way,
Code:
{
Q_OBJECT
...
public:
...
static void Error
(QString value
) //diplays error message {
NDialog dlg("ERROR");
dlg.setAttribute(Qt::WA_DeleteOnClose,false);
dlg.AddWidget(&msg);
connect(&ok,SIGNAL(clicked()),&dlg,SLOT(close()));
dlg.AddWidget(&ok);
dlg.exec();
};
};
or
Code:
{
Q_OBJECT
...
public:
...
static void Error
(QString value
) //diplays error message {
NDialog* dlg = new NDialog("ERROR");
dlg->setAttribute(Qt::WA_DeleteOnClose,false);
dlg->AddWidget(msg);
connect(ok,SIGNAL(clicked()),dlg,SLOT(close()));
connect(ok,SIGNAL(clicked()),dlg,SLOT(deleteLater()));
dlg->AddWidget(ok);
dlg->exec();
};
};
for both of the above examples you don't need to use WA_DeleteOnClose flag
Re: WA_DeleteOnClose and exec()
Ah, apologies. Given how the problem had to do with DeleteOnClose, I took it for granted that the crash occurs when the dialog is closed. And the erros given is a "Debug Assertion Error".
And both methods work, so thanks. What I find odd is that these dialogs work perfectly if they're modeless (::show()), but only crash when they're modal (::exec()).
Re: WA_DeleteOnClose and exec()
Ok, it is obvious that the WA_DeleteOnClose flag if set will delete the dialog when closed, and then as dialog is a object defined on stack it will deleted when the block scope exits, it is here your program will crash, as it is deleting the dialog which is already deleted when you closed it.
So conclusion, use WA_DeleteOnClose flag for objects / widgets created on heap.
Re: WA_DeleteOnClose and exec()
Yes, of course, but you'll see in my original post that it was created on the heap, but was still giving me the crash regardless. I admit that the first time I wrote the code, I created it on the stack and it took me a few seconds to realize how silly it was, so I created it on the heap. The surprise was to find that it still crashed.
Re: WA_DeleteOnClose and exec()
Check again you are you missing something? You still have QLabel and QPushButton defined on stack? which were also deleted when the dialog is deleted, as dialog takes the ownership of the widget when any widget is added to it.
I hope you got my point.
Re: WA_DeleteOnClose and exec()
Ah, correct. Hadn't thought to create all the other objects on the stack. Touché.
Thanks.