0

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

4

1 回答 1

4

dlgProgress->setAttribute(Qt::WA_DeleteOnClose);关闭时删除小部件。正如您所调用dlgProgress->close();的,在此行之后,它指向的对象已被释放,dlgProgress现在是一个无效指针。

您需要dlgProgress在任何调用关闭或事件后使用信号设置为 null Qobject::destroyed()

编辑:

Qt::WA_DeleteOnClose指定如果发生关闭事件,对象将被删除。不确切需要多少时间。例如,如果他们正在使用QObject::deleteLater(),则不会立即删除该对象。即使不是这样,代码片段也像

 A* a = new A;
 a->dosomething();
 delete a;
 a->dosomething();

是未定义的行为。第二次调用a->dosomething();可能会崩溃(如果你幸运的话)或者可能不会崩溃。

于 2013-01-31T10:28:20.133 回答