删除布局会删除其子布局吗? [英] Does deleting layout deletes its sublayouts?

查看:257
本文介绍了删除布局会删除其子布局吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on Qt application. There I am creating layout and adding sublayout. I have seen that calling addLayout() sets as parent the container layout. Does that implies than when I delete superlayout its descendants will get deleted too?

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

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

Will deleting centralWidget delete formLayout? Thanks and regards

推荐答案

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

Concerning Lifetime Management (or in other words: which deletes what), there is an extra chapter in Qt doc.:

对象树&所有权

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

Object Trees & Ownership

QObjects organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's children() list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a QShortcut (keyboard shortcut) is a child of the relevant window, so when the user closes that window, the shortcut is deleted too.

...

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

QWidget, the fundamental class of the Qt Widgets module, extends the parent-child relationship. A child normally also becomes a child widget, i.e. it is displayed in its parent's coordinate system and is graphically clipped by its parent's boundaries. For example, when the application deletes a message box after it has been closed, the message box's buttons and label are also deleted, just as we'd want, because the buttons and label are children of the message box.

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

You can also delete child objects yourself, and they will remove themselves from their parents. For example, when the user removes a toolbar it may lead to the application deleting one of its QToolBar objects, in which case the tool bar's QMainWindow parent would detect the change and reconfigure its screen space accordingly.

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

The debugging functions QObject::dumpObjectTree() and QObject::dumpObjectInfo() are often useful when an application looks or acts strangely.

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

Looking for doc. of QVBoxLayout::addLayout(), I came to:

避免QBoxLayout :: addLayout(QLayout * layout,int Stretch = 0)

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

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

Adds layout to the end of the box, with serial stretch factor stretch.

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

See also insertLayout(), addItem(), and addWidget().

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

which is not very helpful but following the link I ended up in

无效的QLayout :: addItem(QLayoutItem * item)

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

void QLayout::addItem(QLayoutItem *item)

Implemented in subclasses to add an item. How it is added is specific to each subclass.

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

This function is not usually called in application code. To add a widget to a layout, use the addWidget() function; to add a child layout, use the addLayout() function provided by the relevant QLayout subclass.

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

Note: The ownership of item is transferred to the layout, and it's the layout's responsibility to delete it.

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

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

To illustrate this, I made a small sample testQLayoutDelete.cc similar to the exposed code of 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小部件/布局类,重载的析构函数在其中生成相应的调试输出.

I made a little help macro DEBUG_DELETE() to derive every involved Qt widget/layout class, where the overloaded destructor makes a respective debug output.

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

A Qt project file testQLayoutDelete.pro to compile it:

SOURCES = testQLayoutDelete.cc

QT += widgets

在Windows 10上的 cygwin64 中进行了编译和测试:

Compiled and tested in cygwin64 on Windows 10:

$ qmake-qt5 testQLayoutDelete.pro

$ make && ./testQLayoutDelete
Qt Version: 5.9.4

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

After clicking the × button, the interesting output appears:

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

$

这篇关于删除布局会删除其子布局吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆