背景:
我查看了一些代码,并制作了一个用于显示错误的本地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((。
我很困惑,因为我想:
- QWidgets只在堆上工作
- 当消息框关闭时,指针将自动
delete error;
我尝试将QMessageBox放在堆栈上,但它没有显示。
问题:
- 我可以把这个QMessageBox放在堆栈上并让它工作吗?我应该吗
- 是否需要显式
delete
QMessageBox指针 - 为什么在这种情况下,将父项设置为0以外的值很重要
原则上,您可以在堆栈上创建一个QWidget对象。在这里,它不起作用,因为对error->show()
的调用不会立即显示消息框,它只是在返回主偶数循环时安排一个显示,此时对象将被销毁。因此,delete
和QMessageBox
也不起作用。当父对象本身被销毁时,设置父对象会将对象销毁的责任交给父对象,这是一个好主意。
但是,如果我理解您想要做什么,那么您需要等待用户在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树遍历函数仍然可以访问指针。