本页内容

QGraphicsLayout Class

QGraphicsLayout 类是 Graphics View 中所有布局的基类。更多内容...

头文件: #include <QGraphicsLayout>
CMake: find_package(Qt6 REQUIRED COMPONENTS Widgets)
target_link_libraries(mytarget PRIVATE Qt6::Widgets)
qmake: QT += widgets
继承自: QGraphicsLayoutItem
继承自:

QGraphicsAnchorLayout、QGraphicsGridLayout 以及QGraphicsLinearLayout

公共函数

QGraphicsLayout(QGraphicsLayoutItem *parent = nullptr)
virtual ~QGraphicsLayout()
void activate()
virtual int count() const = 0
virtual void invalidate()
bool isActivated() const
virtual QGraphicsLayoutItem *itemAt(int i) const = 0
virtual void removeAt(int index) = 0
void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
virtual void widgetEvent(QEvent *e)

重新实现的公共函数

virtual void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const override
virtual void updateGeometry() override

受保护函数

void addChildLayoutItem(QGraphicsLayoutItem *layoutItem)

详细说明

QGraphicsLayout 是一个抽象类,它为QGraphicsWidget 定义了一个虚拟 API,用于排列QGraphicsWidget 子元素和其他QGraphicsLayoutItem 对象。QGraphicsWidget 通过QGraphicsWidget::setLayout()将责任分配给一个QGraphicsLayout。当小部件调整大小时,布局会自动排列小部件的子元素。 QGraphicsLayout继承自QGraphicsLayoutItem ,因此它可以由任何布局进行管理,包括其自身的子类。

编写自定义布局

您可以使用 QGraphicsLayout 作为基础来编写自己的自定义布局(例如,flowlayout),但更常见的做法是直接使用其子类之一——QGraphicsLinearLayout 或QGraphicsGridLayout 。在创建自定义布局时,至少必须重写以下函数:

函数描述
QGraphicsLayoutItem::setGeometry()当布局的几何属性被设置时发出通知。您可以在重写此函数时,将几何属性存储在您自己的布局类中。
QGraphicsLayoutItem::sizeHint()返回布局的大小提示。
QGraphicsLayout::count()返回布局中的项目数量。
QGraphicsLayout::itemAt()返回布局中某项的指针。
QGraphicsLayout::removeAt()从布局中移除一个项目,但不会销毁该项目。

有关如何实现每个函数的更多详细信息,请参阅各函数的文档。

每种布局都定义了自己的 API 来排列控件和布局项。例如,对于网格布局,您需要行和列索引,并可选地指定行和列跨度、对齐方式、间距等。 然而,线性布局仅需一个行或列索引来定位其项目。对于网格布局,插入顺序不会以任何方式影响布局,但对于线性布局,顺序至关重要。在编写自己的布局子类时,您可以自由选择最适合您布局的 API。

QGraphicsLayout 提供了addChildLayoutItem() 便捷函数,用于将布局项添加到自定义布局中。如果需要,该函数会自动为图形项重新设置父对象。

激活布局

当布局的几何属性发生变化时,QGraphicsLayout 会立即通过调用每个项目的 `setGeometry()` 方法,重新排列其管理的所有项目。这种重新排列称为“激活布局”。

QGraphicsLayout 会更新自身的几何信息,使其与所管理的QGraphicsLayoutItem 的contentsRect()结果保持一致。因此,当控件被调整大小时,它会自动重新排列所有项目。QGraphicsLayout 会缓存所有受管项目的大小,以避免过频地调用setGeometry()。

注意: QGraphicsLayout的 几何形状将与其被分配到的控件(而非布局本身)的contentsRect() 结果一致。

隐式激活布局

可以通过以下两种方式之一隐式激活布局:调用activate()或调用invalidate()。调用activate()会立即激活布局。相比之下,调用invalidate()会延迟生效,因为它会向受管理的控件发布一个LayoutRequest 事件。由于事件压缩机制,activate()仅会在控制权返回事件循环后被调用一次。 这被称为“使布局失效”。使布局失效也会使任何缓存信息失效。此外,invalidate() 函数是一个虚函数。因此,您可以在 QGraphicsLayout 的子类中通过重写此函数来使自己的缓存失效。

事件处理

QGraphicsLayout 通过虚拟事件处理函数widgetEvent() 监听其所管理小部件的事件。当布局被分配给某个小部件时,所有发送到该小部件的事件都会首先由widgetEvent() 进行处理。这使得布局能够感知小部件上的任何相关状态变化,例如可见性变化或布局方向变化。

边距处理

可以通过重写setContentsMargins() 和getContentsMargins() 来修改 QGraphicsLayout 的边距。

成员函数文档

QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutItem *parent = nullptr)

创建一个 QGraphicsLayout 对象。

parent 该对象将被传递给QGraphicsLayoutItem 的构造函数,并且QGraphicsLayoutItem 的isLayout参数将被设置为true。

如果parent 是QGraphicsWidget ,则该布局将安装到该小部件上。(请注意,安装新布局会删除已安装的旧布局。)

[virtual noexcept] QGraphicsLayout::~QGraphicsLayout()

销毁QGraphicsLayout 对象。

void QGraphicsLayout::activate()

激活布局,导致布局中的所有项目立即重新排列。该函数的工作原理是先调用count()和itemAt(),然后依次对所有项目调用setGeometry()。激活后,布局将根据其父节点的contentsRect()调整其几何属性。随后,父节点将使其自身的任何布局失效。

如果按顺序或递归地调用此函数(例如,由某个已排列的项目在响应调整大小时调用),则该函数将不执行任何操作。

请注意,布局可以自由使用几何缓存来优化此过程。若要强制失效此类缓存,可在调用 `activate()` 之前调用 `invalidate()`。

另请参阅 invalidate()。

[protected] void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem)

此函数是为自定义布局提供的便捷函数,它将遍历布局中的所有项目,并将这些项目的图形元素重新关联到布局中最近的QGraphicsWidget 父节点。

如果layoutItem 已位于另一个布局中,则会将其从该布局中移除。

如果自定义布局需要特殊行为,可以忽略此函数,并实现自己的行为。

另请参阅 graphicsItem()。

[pure virtual] int QGraphicsLayout::count() const

必须在QGraphicsLayout 的子类中重写此纯虚函数,以返回布局中的项目数量。

子类可以自由决定如何存储这些项目。

另请参阅 itemAt() 和removeAt()。

[override virtual] void QGraphicsLayout::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const

重写了:QGraphicsLayoutItem::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const。

[virtual] void QGraphicsLayout::invalidate()

清除布局中缓存的任何几何体和尺寸提示信息,并向受管父元素QGraphicsLayoutItem 发布一个LayoutRequest 事件。

另请参阅 activate() 和setGeometry()。

bool QGraphicsLayout::isActivated() const

如果布局当前正在被激活,则返回true ;否则,返回false 。如果布局正在被激活,这意味着它当前正在重新排列其项目(即已调用activate()函数,但该函数尚未返回)。

另请参阅 activate() 和invalidate()。

[pure virtual] QGraphicsLayoutItem *QGraphicsLayout::itemAt(int i) const

此纯虚函数必须在QGraphicsLayout 的子类中重写,以返回索引i 处项的指针。重写时可以假设i 是有效的(即,它遵循count()的返回值)。该函数与count()共同作为遍历布局中所有项的手段。

子类可以自由决定如何存储项目,且视觉布局无需通过此函数体现。

另请参阅 count() 和removeAt()。

[pure virtual] void QGraphicsLayout::removeAt(int index)

必须在QGraphicsLayout 的子类中重写此纯虚拟函数,以从index 中移除该项。重写时可以假设index 是有效的(即,它遵循count()的返回值)。

该实现必须确保被移除项的parentLayoutItem() 不再指向此布局,因为该项已被视为从布局层次结构中移除。

如果布局要在不同应用程序之间重用,我们建议布局删除该项目,但图形视图框架并不依赖于此。

子类可以自由决定如何存储这些项目。

另请参阅 itemAt() 和count()。

void QGraphicsLayout::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)

将内容边距设置为left 、top 、right 和bottom 。顶级布局的默认内容边距取决于样式(通过查询 pixelMetric 获取QStyle::PM_LayoutLeftMargin 、QStyle::PM_LayoutTopMargin 、QStyle::PM_LayoutRightMargin 和QStyle::PM_LayoutBottomMargin 的值)。

对于子布局,默认边距为 0。

更改内容边距会自动使布局失效。

另请参阅 invalidate()。

[override virtual] void QGraphicsLayout::updateGeometry()

重写了:QGraphicsLayoutItem::updateGeometry()。

[virtual] void QGraphicsLayout::widgetEvent(QEvent *e)

此虚拟事件处理程序会接收托管控件的所有事件。QGraphicsLayout 使用此事件处理程序来监听与布局相关的事件,例如几何属性变化、布局变化或布局方向变化。

e 是该事件的指针。

您可以重写此事件处理程序,以跟踪您自定义布局中的类似事件。

另请参阅 QGraphicsWidget::event() 和QGraphicsItem::sceneEvent()。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.