你能把QWidget放到堆栈上吗



背景:

我查看了一些代码,并制作了一个用于显示错误的本地QMessageBox,并将其分配到堆中:

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

开发商表示:

此指针将泄漏,您没有设置父项,也从未删除它。在这里你也不需要指针。至于父母不要使用0,但使用Core::ICore::mainWindow((。

我很困惑,因为我想:

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

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


问题:

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

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

但是,如果我理解您想要做什么,那么您需要等待用户在return之前单击"确定"按钮。如果是这种情况,您最好使用静态QMessageBox函数,例如QMessageBox::warning。

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

error->setAttribute(Qt::WA_DeleteOnClose);

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

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

因为当线程超出作用域时,它会立即被销毁。您必须使用QMessageBox::exec()才能在块模式下运行它。

QWidget on stack可以工作,但在大多数情况下并不实用,因为当作用域保留时,堆栈上的对象会被删除。

看看任何(很多(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 on stack"这个问题——它应该是证明,它是有效的和官方的。但同样,这个和QDialog::exec是栈上QWidget的唯一用例。

2( 它不会有害处。如果您的编码规则要求为每个新的调用delete,请执行该操作。否则,请正确设置Qt::WA_DeleteClose,并在关闭时将其删除。

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

最新更新