删除布局会删除其子布局吗?

时间:2018-11-04 12:00:34

标签: qt5 parent-child qwidget qlayout

我正在研究Qt应用程序。在那里,我正在创建布局并添加子布局。 我已经看到调用addLayout()将容器布局设置为父级。 这是否意味着比我删除超级布局时其后代也将被删除?

QWidget* centralWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);
QFormLayout *formLayout = new QFormLayout;
mainLayout->addLayout(formLayout);

将删除centralWidget删除formLayout吗? 谢谢和问候

1 个答案:

答案 0 :(得分:1)

关于生命周期管理(或换句话说:删除内容),Qt文档中还有一章:

  

"startup-script-url"

     

QObject在对象树中进行组织。当您创建一个以另一个对象作为父对象的QObject时,它将被添加到父对象的children()列表中,而当父对象为父对象时将其删除。事实证明,这种方法非常适合GUI对象的需求。例如,QShortcut(键盘快捷方式)是相关窗口的子级,因此当用户关闭该窗口时,快捷方式也会被删除。

...

  

QWidget是Qt Widgets模块的基本类,它扩展了父子关系。子级通常也成为子级小部件,即,它显示在其父级的坐标系中,并通过其父级的边界以图形方式进行裁剪。例如,当应用程序在关闭后删除消息框时,消息框的按钮和标签也会被删除,就像我们想要的那样,因为按钮和标签是消息框的子元素。

     

您还可以自己删除子对象,它们将从自己的父母中删除。例如,当用户删除工具栏时,它可能导致应用程序删除其QToolBar对象之一,在这种情况下,工具栏的QMainWindow父级将检测到更改并相应地重新配置其屏幕空间。

     

当应用程序外观或行为异常时,调试功能QObject :: dumpObjectTree()和QObject :: dumpObjectInfo()通常很有用。

正在寻找文件。 QVBoxLayout::addLayout()中,我来到了:

  

Object Trees & Ownership

     

在框的末尾添加布局,并进行串行拉伸因子拉伸。

     

另请参见insertLayout(),addItem()和addWidget()。

这不是很有帮助,但是按照我最终链接的链接

  

void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

     

在子类中实现以添加项目。如何添加它特定于每个子类。

     

在应用程序代码中通常不调用此函数。要将小部件添加到布局,请使用addWidget()函数;要添加子布局,请使用相关QLayout子类提供的addLayout()函数。

     

注意:项目的所有权已转移到版式,版式有责任删除它。

项目的所有权已转移到版式中,版式有责任将其删除。

为了说明这一点,我制作了一个小样本testQLayoutDelete.cc,类似于OP的公开代码:

#include <QtWidgets>

#define DEBUG_DELETE(CLASS) \
struct CLASS: Q##CLASS { \
  CLASS(QWidget *pQParent = nullptr): Q##CLASS(pQParent) { } \
  virtual ~CLASS() { qDebug() << #CLASS"::~"#CLASS"();"; } \
}

DEBUG_DELETE(Widget);
DEBUG_DELETE(VBoxLayout);
DEBUG_DELETE(FormLayout);
DEBUG_DELETE(PushButton);

int main(int argc, char *argv[])
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup UI
  QWidget *pQCentralWidget = new Widget();
  QVBoxLayout *pQMainLayout = new VBoxLayout(pQCentralWidget);
  QFormLayout *pQFormLayout = new FormLayout;
  QPushButton *pQButton = new PushButton();
  pQFormLayout->addRow(QString("The button: "), pQButton);
  pQMainLayout->addLayout(pQFormLayout);
  pQCentralWidget->show();
  // enter runtime loop
  int ret = app.exec();
  // clean up explicitly (for illustration of recursive destruction)
  qDebug() << "delete pQCentralWidget;";
  delete pQCentralWidget;
  // done
  qDebug() << "return ret;";
  return ret;
}

我做了一个小的帮助宏DEBUG_DELETE()来派生每个涉及的Qt小部件/布局类,重载的析构函数在其中生成相应的调试输出。

要编译的Qt项目文件testQLayoutDelete.pro

SOURCES = testQLayoutDelete.cc

QT += widgets

已在Windows 10的void QLayout::addItem(QLayoutItem *item)中进行了编译和测试:

$ qmake-qt5 testQLayoutDelete.pro

$ make && ./testQLayoutDelete
Qt Version: 5.9.4

cygwin64

单击×按钮后,将显示有趣的输出:

delete pQCentralWidget;
Widget::~Widget();
VBoxLayout::~VBoxLayout();
FormLayout::~FormLayout();
PushButton::~PushButton();
return ret;

$