Reputation: 886
I have problem in ensuring the dialog is closed/released with the following Qt codes.
//Segment 1: To open a 'wait' dialog for some long-running tasks
void MainWindow::ui_showProgressDialog(QString title) {
dlgProgress = new QProgressDialog(title, tr("Cancel"), 0, 0, this);
dlgProgress->setAttribute(Qt::WA_DeleteOnClose); // line 1
dlgProgress->setModal(true);
dlgProgress->show();
connect(voidWatcher, SIGNAL(finished()),
this, SLOT(onPopulationFile()));
}
//Segment 2: Attempts to close the 'wait' dialog
void MainWindow::onPopulationFile() {
qDebug((dlgProgress == NULL) ? "true" : "false");
if (dlgProgress) //
{
qDebug("0");
dlgProgress->close(); // line 2
qDebug("1");
}
qDebug((dlgProgress == NULL) ? "true" : "false");
}
Issue: When I trigger the call 'ui_showProgressDialog' twice, the second call always crash my program. Originally, my code has no line 1 of segment 1, and from the QtCreator, it always crashes on line 2 of segment 2. Debug message shows as follow
// first call to onPopulationFile
false
0
1
false
// second call to onPopulationFile
false
0
*** CRASH ***
I read the documentation that NEVER delete objects from different threads, I'm doubt that the call 'onPopulationFile' is invoked from a non-main thread. So I added the line 1 to segment to let the program decide when the delete the object. But it seems not work. Any suggestion to the problem?
Experiment done: If I replace QProgressDialog with QDialog, the program goes without crashes, and the debug message show
// first call to onPopulationFile
false
0
1
false
// second call to onPopulationFile
false
0
1
false
So,
Platform: Qt Opensource 4.8 (x64), Windows 7 (x64), MinGW (rubenvb 4.7.2)
Upvotes: 0
Views: 4855
Reputation: 22910
dlgProgress->setAttribute(Qt::WA_DeleteOnClose);
deletes the widget when it is closed. As you are calling dlgProgress->close();
, after this line the object it points to has been freed, and dlgProgress
is now a invalid pointer.
You need to set dlgProgress
to null after any call to close, or event better, use the signal Qobject::destroyed()
.
EDIT:
Qt::WA_DeleteOnClose
specify that the object will be deleted if a close event happens. Not exactly how much time it will take. For instance if they are using QObject::deleteLater()
, then the object is not deleted right away. Even if it is not the case , pieces of code like
A* a = new A;
a->dosomething();
delete a;
a->dosomething();
are undefined behavior. The second call to a->dosomething();
may crash (if you are lucky) or may not crash.
Upvotes: 4