我在确保使用以下Qt代码关闭/释放对话框时遇到问题。
//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");
}
问题:当我两次触发调用'ui_showProgressDialog'时,第二次调用总是使程序崩溃。最初,我的代码没有第1段的第1行,而且从QtCreator开始,它总是在第2段的第2行崩溃。调试消息显示如下
// first call to onPopulationFile
false
0
1
false
// second call to onPopulationFile
false
0
*** CRASH ***
我阅读的文档绝不会从不同的线程中删除对象,我怀疑从非主线程调用'onPopulationFile'调用。所以我将第1行添加到段中,让程序决定删除对象的时间。但似乎行不通。对此问题的任何建议?
完成实验:如果我用QDialog替换QProgressDialog,程序没有崩溃,调试消息显示
// first call to onPopulationFile
false
0
1
false
// second call to onPopulationFile
false
0
1
false
所以,
平台:Qt Opensource 4.8(x64),Windows 7(x64),MinGW(rubenvb 4.7.2)
答案 0 :(得分:3)
dlgProgress->setAttribute(Qt::WA_DeleteOnClose);
在窗口小部件关闭时删除它。在调用dlgProgress->close();
时,在此行之后,它指向的对象已被释放,dlgProgress
现在是无效指针。
您需要在关闭任何调用后将dlgProgress
设置为null,或者事件更好,请使用信号Qobject::destroyed()
。
编辑:
Qt::WA_DeleteOnClose
指定在发生close事件时删除对象。不完全 需要多长时间 。例如,如果他们使用QObject::deleteLater()
,则不会立即删除该对象。即使不是这样,代码片段如
A* a = new A;
a->dosomething();
delete a;
a->dosomething();
是未定义的行为。对a->dosomething();
的第二次调用可能会崩溃(如果您很幸运)或者可能不会崩溃。