为什么这个QT应用程序会退出SIGABRT信号?

Vel*_*rok 2 c++ opengl qt4 sigabrt

我是Qt的新手.所以我开始重新实现一个入门示例:链接.

但是我关闭窗口时会收到SIGABRT信号.其原因很明显是由于一些内存管理错误.

您可以在下面找到callstack和相关代码.该行editWindow.setLayout(&layout);导致错误.布局类是否在销毁时删除小部件,因此要求拥有它们?

什么是这种行为的原因?以及如何解决它?

最好的祝福.

信息
调用
调用堆栈

资源

  QPushButton testButton("Test");

  QVBoxLayout layout;
  layout.addWidget(&testButton);

  QWidget editWindow;
  // the following line is the source of the error
  editWindow.setLayout(&layout);
  editWindow.show();

  int val = app.exec();
Run Code Online (Sandbox Code Playgroud)

Kal*_*son 7

许多不同的Qt函数将获取传递的对象的所有权,这意味着它承担对所有内存管理的控制并在删除时释放它.从setLayout文档:

QWidget将获得布局的所有权.

在您调用setLayout它之后,它具有父节点,并且除了在清除方法的堆栈时删除它之外,它的父节点将删除它.因此,它被删除两次导致问题.

如果其他一切都是正确的,这个改变应该解决它:

QVBoxLayout *layout = new QVBoxLayout();
//...
layout->addWidget(&testButton);
//...
editWindow.setLayout(layout);
Run Code Online (Sandbox Code Playgroud)

另外,请注意,创建主窗口小部件然后分配将在该窗口小部件上显示为父窗口的窗口小部件是典型的.换句话说,我希望更像下面的东西(尽管不是绝对必要的).这也有助于确保如果某些事情在未来得到重新定位,您将不会遇到问题:

QWidget editWindow;
QVBoxLayout *layout = new QVBoxLayout();
QPushButton *testButton = new QPushButton(&editWindow);
layout->addWidget(testButton);
editWindow.setLayout(layout);
editWindow.show();
int val = app.exec();
Run Code Online (Sandbox Code Playgroud)

大多数重新配置的Qt对象以及可能发生的所有权更改都将具有接受QWidget*或的构造函数QObject*.