你能把QWidgets放到栈上吗?
Can you put QWidgets on the stack?
背景故事:
我审查了我的一些代码,我制作了一个本地 QMessageBox
用于显示错误,并将其分配给堆:
if (getAutopilotList.error() == 0) {
QMessageBox* error = new QMessageBox(0);
error->setDetailedText(getAutopilotList.errorString());
error->setText("something");
error->setWindowTitle(tr("Error!"));
error->show();
return;
}
开发者说:
This pointer will leak, you are setting no parent and you never delete
it. Here as well you do not need a pointer. As for the parent do not
use 0, but Core::ICore::mainWindow().
我很困惑,因为我认为:
- QWidgets 只在堆上工作
- 当消息框关闭时指针会自动
delete error;
。
我试过把QMessageBox放到栈上,但是没有显示。
问题:
- 我可以将这个 QMessageBox 放在堆栈上并让它工作吗?
- 我是否需要显式
delete
QMessageBox 指针?
- 为什么在这种情况下将父级设置为大于 0 的值很重要?
I tried putting the QMessageBox on the stack, but it did not show.
因为当线程超出范围时它会立即被销毁。您必须在块模式下使用 QMessageBox::exec()
到 运行。
原则上可以在栈上创建QWidget对象。在这里,它不起作用,因为对 error->show()
的调用不会立即显示消息框,它只是安排在返回主偶数循环时显示,此时对象将被销毁。因此,delete
ing QMessageBox
也不起作用。设置父级将对象销毁的责任交给父级,当父级本身被销毁时,这是一个好主意。
但是,如果我理解你想要做什么,你想在 return
之前等待用户点击确定按钮。如果是这样的话,你最好使用静态的QMessageBox
函数,比如QMessageBox::warning。
如果你想要一个持久的消息框,那么你的代码是可以的,但是你应该添加以下调用:
error->setAttribute(Qt::WA_DeleteOnClose);
这将在相应的window关闭时触发删除。
堆栈上的 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 on stack"- 它应该是有效的和官方的证明。但是这和 QDialog::exec 是堆栈上 QWidgets 的唯一用例。
2) 不会有伤害的。如果您的编码规则要求为每个新的调用 delete - 执行它。否则,请正确设置 Qt::WA_DeleteOnClose,并在关闭时将其删除。
3)关于父对象 0:当失去对具有父对象的指针的引用时,您是安全的。如果父项被删除,所有子项都会自动删除(还有那些,您可能已经忘记了)。所以对于长运行的应用程序,"memory leak"只是暂时的。
在 parent =0 的情况下,它不会在 C++ 意义上泄漏,这使得内存检查器无法检测到此类泄漏。使用一些 QObject 树遍历函数仍然可以访问该指针。
背景故事:
我审查了我的一些代码,我制作了一个本地 QMessageBox
用于显示错误,并将其分配给堆:
if (getAutopilotList.error() == 0) {
QMessageBox* error = new QMessageBox(0);
error->setDetailedText(getAutopilotList.errorString());
error->setText("something");
error->setWindowTitle(tr("Error!"));
error->show();
return;
}
开发者说:
This pointer will leak, you are setting no parent and you never delete it. Here as well you do not need a pointer. As for the parent do not use 0, but Core::ICore::mainWindow().
我很困惑,因为我认为:
- QWidgets 只在堆上工作
- 当消息框关闭时指针会自动
delete error;
。
我试过把QMessageBox放到栈上,但是没有显示。
问题:
- 我可以将这个 QMessageBox 放在堆栈上并让它工作吗?
- 我是否需要显式
delete
QMessageBox 指针? - 为什么在这种情况下将父级设置为大于 0 的值很重要?
I tried putting the QMessageBox on the stack, but it did not show.
因为当线程超出范围时它会立即被销毁。您必须在块模式下使用 QMessageBox::exec()
到 运行。
原则上可以在栈上创建QWidget对象。在这里,它不起作用,因为对 error->show()
的调用不会立即显示消息框,它只是安排在返回主偶数循环时显示,此时对象将被销毁。因此,delete
ing QMessageBox
也不起作用。设置父级将对象销毁的责任交给父级,当父级本身被销毁时,这是一个好主意。
但是,如果我理解你想要做什么,你想在 return
之前等待用户点击确定按钮。如果是这样的话,你最好使用静态的QMessageBox
函数,比如QMessageBox::warning。
如果你想要一个持久的消息框,那么你的代码是可以的,但是你应该添加以下调用:
error->setAttribute(Qt::WA_DeleteOnClose);
这将在相应的window关闭时触发删除。
堆栈上的 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 on stack"- 它应该是有效的和官方的证明。但是这和 QDialog::exec 是堆栈上 QWidgets 的唯一用例。
2) 不会有伤害的。如果您的编码规则要求为每个新的调用 delete - 执行它。否则,请正确设置 Qt::WA_DeleteOnClose,并在关闭时将其删除。
3)关于父对象 0:当失去对具有父对象的指针的引用时,您是安全的。如果父项被删除,所有子项都会自动删除(还有那些,您可能已经忘记了)。所以对于长运行的应用程序,"memory leak"只是暂时的。 在 parent =0 的情况下,它不会在 C++ 意义上泄漏,这使得内存检查器无法检测到此类泄漏。使用一些 QObject 树遍历函数仍然可以访问该指针。