QDialog关闭崩溃

时间:2013-01-31 10:13:04

标签: qt qdialog

我在确保使用以下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

所以,

  • 为什么第2段中的第二个空测试总是失败? [编辑:我必须将变量显式设置为NULL]
  • 有没有更好的方法可以关闭'等待'对话框?
  • 我尝试关闭/释放对话框,因为我想尽快释放内存。我真的需要手动删除对话框吗?

平台:Qt Opensource 4.8(x64),Windows 7(x64),MinGW(rubenvb 4.7.2)

1 个答案:

答案 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();的第二次调用可能会崩溃(如果您很幸运)或者可能不会崩溃。