4

背景故事:

我审查了一些代码,并创建了一个本地QMessageBox显示错误,并将其分配给堆:

if (getAutopilotList.error() == 0) {
    QMessageBox* error = new QMessageBox(0);
    error->setDetailedText(getAutopilotList.errorString());
    error->setText("something");
    error->setWindowTitle(tr("Error!"));
    error->show();
    return;
}

开发商说:

这个指针会泄漏,你没有设置父级并且你永远不会删除它。这里也不需要指针。至于parent不要使用0,而是Core::ICore::mainWindow()。

我很困惑,因为我想:

  1. QWidgets 只在堆上工作
  2. delete error;当消息框关闭时指针会自动关闭。

我尝试将 QMessageBox 放在堆栈上,但没有显示。


问题:

  1. 我可以把这个 QMessageBox 放在堆栈上并让它工作吗,我应该吗?
  2. 我需要明确deleteQMessageBox 指针吗?
  3. 在这种情况下,为什么将父级设置为 0 以外的值很重要?
4

3 回答 3

4

我尝试将 QMessageBox 放在堆栈上,但没有显示。

因为当线程超出范围时它会立即被销毁。您必须使用QMessageBox::exec()以块模式运行它。

于 2015-05-30T22:22:36.370 回答
4

原则上,您可以在堆栈上创建一个 QWidget 对象。在这里,它不起作用,因为调用error->show()不会立即显示消息框,它只是在返回主偶数循环时安排显示,此时对象将被销毁。出于这个原因,deleteing theQMessageBox也不会起作用。设置父级将对象销毁的责任交给了父级,当父级本身被销毁时,这是一个好主意。

但是,如果我了解您想要做什么,您希望等待用户在return. 如果是这种情况,您最好使用静态QMessageBox函数,例如QMessageBox::warning

如果您想要一个持久的消息框,那么您的代码是可以的,但您应该添加以下调用:

error->setAttribute(Qt::WA_DeleteOnClose);

这将在相应窗口关闭时触发删除。

于 2015-05-30T22:22:59.403 回答
3

堆栈上的 QWidget 有效,但在大多数情况下不实用,因为堆栈上的对象在离开范围时被删除。

看一下任何(多对多)Qt 示例,您会发现以下模式:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);   
    MainWindow window; //inherits from QWidget, created on stack
    window.show();    
    return app.exec();
}

1)关于“堆栈上的QWidget”这个问题-应该证明它有效且正式。但同样,这和 QDialog::exec 是堆栈上 QWidgets 的唯一用例。

2)它不会伤害。如果您的编码规则需要为每个新的调用删除 - 这样做。否则,正确设置 Qt::WA_DeleteOnClose,并在关闭时将其删除。

3)关于父 0:当失去对具有父的指针的引用时,您是安全的。如果父级被删除,所有子级都会被自动删除(还有那些,你可能已经忘记了)。所以对于长时间运行的应用程序,“内存泄漏”只是暂时的。在 parent =0 的情况下,它不会在 c++ 意义上泄漏,这使得内存检查器无法检测到此类泄漏。指针仍然可以使用一些 QObject-tree 遍历函数来访问。

于 2015-05-30T22:45:03.733 回答