创建小工具时通常不会设置任何伸展系数。在布局中布置部件时,会根据其
QWidget::sizePolicy
() 或最小尺寸提示(以较大者为准)分配空间。拉伸因子用于改变部件之间的空间比例。
如果我们使用
QHBoxLayout
布局三个部件,且未设置拉伸因子,我们将得到如下布局:
如果我们对每个部件应用拉伸因子,它们将按比例布局(但绝不会小于其最小尺寸提示),例如
当你制作自己的 widget 类时,你也应该传达它的布局属性。如果 widget 使用 Qt 的布局之一,这一点已经得到了处理。如果 widget 没有任何子 widget,或者使用的是手动布局,则可以使用以下任何或所有机制来更改 widget 的行为:
重新实现
QWidget::sizeHint
() 以返回 widget 的首选尺寸。
重新实现
QWidget::minimumSizeHint
() 以返回 widget 的最小尺寸。
调用
QWidget::setSizePolicy
() 来指定 widget 的空间要求。
每当尺寸提示、最小尺寸提示或尺寸策略发生变化时,请调用
QWidget::updateGeometry
() 。这将导致布局重新计算。多次连续调用
QWidget::updateGeometry
() 只会导致一次布局重新计算。
如果部件的首选高度取决于其实际宽度(例如,具有自动分词功能的标签),请在部件的
size policy
中设置
height-for-width
标志,并重新实现
QWidget::heightForWidth
()。
即使您实现了
QWidget::heightForWidth
(),提供合理的 sizeHint() 也不失为一个好主意。
有关实现这些函数的进一步指导,请参阅《
Qt 季刊
》文章《
用高度换宽度
》。
在标签部件中使用富文本会给其父部件的布局带来一些问题。出现问题的原因是 Qt 的布局管理器在对标签进行文字包装时处理富文本的方式。
在某些情况下,父布局会进入 QLayout::FreeResize 模式,这意味着它不会调整其内容布局以适应小尺寸窗口,甚至不会阻止用户将窗口设置得太小而无法使用。可以通过对有问题的部件进行子类化,并实现合适的
sizeHint
() 和
minimumSizeHint
() 函数来解决这个问题。
在某些情况下,向部件添加布局时也会出现这种情况。当您设置
QDockWidget
或
QScrollArea
(使用
QDockWidget::setWidget
() 和
QScrollArea::setWidget
()) 的部件时,必须已经在该部件上设置了布局。否则,该 widget 将不可见。
如果要制作独一无二的特殊布局,也可以按上述方法制作自定义 widget。重新实现
QWidget::resizeEvent
() 以计算所需的尺寸分布,并在每个子控件上调用
setGeometry
() 。
当需要重新计算布局时,该 widget 将收到
QEvent::LayoutRequest
类型的事件。重新实现
QWidget::event
() 以处理
QEvent::LayoutRequest
事件。
如何编写自定义布局管理器
除手动布局外,您还可以通过子类化
QLayout
来编写自己的布局管理器。
Flow Layout
示例展示了如何做到这一点。
下面我们将详细介绍一个示例。
CardLayout
类的灵感来源于同名的 Java 布局管理器。它将项目(窗口小部件或嵌套布局)排列在彼此之上,每个项目的偏移量为
QLayout::spacing
()。
要编写自己的布局类,必须定义以下内容:
用于存储布局所处理项目的数据结构。每个项都是一个
QLayoutItem
。本例中我们将使用
QList
。
addItem
(),如何将项目添加到布局中。
setGeometry
(),如何执行布局。
sizeHint
(),布局的首选尺寸。
itemAt
(), 如何遍历布局。
takeAt
(), 如何从布局中删除项目。
在大多数情况下,您还将实现
minimumSize
().
实现文件 (
card.cpp
)
首先,我们定义
count()
来获取列表中的条目数。