【问题标题】:QDialog closing crashQDialog关闭崩溃
【发布时间】:2013-01-31 10:13:03
【问题描述】:

我在确保使用以下 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 行添加到段中,让程序决定何时删除对象。但这似乎行不通。对这个问题有什么建议吗?

实验完成:如果我将 QProgressDialog 替换为 QDialog,程序不会崩溃,并且会显示调试消息

// 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)

【问题讨论】:

  • 什么是voidWatcherfinished的用途是什么?
  • voidWatcher 是 QFutureWatcher 类型

标签: qt qdialog


【解决方案1】:

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

【讨论】:

  • 感谢您的评论,但是 1) 语句 qDebug("1") 没有使用 dlgProgress 中的任何内容,为什么它无法显示在调试消息中? 2)将信号destroy()连接到哪里?
  • 我不是在谈论调试。我说的是第二次调用该方法时崩溃的根源...
  • 第二次调用 onPopulationFile 的第一个“假”显示在第二次调用中输入 onPopoulationFile 时“dlgProgress”不为空。我的问题是为什么 QDialog 工作,但 QProgressDialog 失败!
  • 感谢您的信息。我编辑了我的程序,现在看起来很顺利。
猜你喜欢
  • 1970-01-01
  • 2014-07-06
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-17
  • 1970-01-01
相关资源
最近更新 更多