1. 布局系统的功能
在 Qt 中,布局系统可以完成:
- 定位子控件
- 得知窗体默认大小
- 得知窗体最小大小
- 窗体大小变化时进行布局排版
- 内容改变(字体大小,隐藏,显示,移除等)时进行布局排版
2. 布局系统的结构
Qt 提供了 QLayout 类及其子类来为界面进行排版布局,结构如下:
QObject QLayoutItem
|______________|
|
QLayout
_________________|__________________
| | | |
QBoxLayout QFormLayout QGridLayou QStackedLayout
______|_______
| |
QHBoxLayout QVBoxLayout
QLayout 是布局系统中的抽象类,继承自 QObject 和 QLayoutItem,其中四个子类为:
- QBoxLayout(箱式布局)
- QFormLayout(表单布局)
- QGridLayout(网格布局)
- QStackedLayout(栈布局)
3. 控件大小
对于控件大小,最重要的两个属性是 sizeHint
和 minimumSizeHint
,这是 QWidget 的属性,是只读属性,sizeHint
为控件的建议大小,对于不同的控件,有不同的建议大小。同理 minimumSizeHint
为建议的最小大小。
4. 大小策略 - QSizePolicy
QSizePolicy::Fixed
: 只能使用sizeHint
的大小,任何操作都不会改变控件大小,固定大小QSizePolicy::Minimum
:sizeHint
最小,控件可以被拉伸,被动拉大QSizePolicy::Maximum
:sizeHint
最大,控件可以被压缩,被动缩小QSizePolicy::Preferred
:sizeHint
为建议大小,控件即可以被压缩,也可以被拉伸 被动伸缩QSizePolicy::MinimumExpanding
:sizeHint
为最小,不能被压缩,被拉伸优先级高 主动扩张QSizePolicy::Expanding
:sizeHint
为建议大小,可以被压缩,被拉伸优先级高 主动扩张,可缩小QSizePolicy::Ignored
:sizeHint
的值会被忽略 | 枚举常量 | 拉伸特点 | 描述 | | —- | —- | :—- | | Fixed | 固定 | 只能使用sizeHint的大小,任何操作都不会改变控件的大小 | | Minimum | 被动拉大 | 以建议尺寸为最小尺寸,如果有多余的空间就拉伸,没有多余就保持建议尺寸。被动扩张 | | Maximum | 被动缩小 | 以建议尺寸为最大尺寸,窗口缩小时,如果其他控件需要,该控件可以尽量缩小为其他控件腾出空间 | | Preferred | 被动伸缩 | 能屈能伸,窗口缩小时可以为其它控件腾出空间,窗口变大时,也可以占据其他控件不需要的空间 | | MinimumExpanding | 主动扩张 | 以建议尺寸为最小尺寸,主动扩张,尽可能占据新增区域 | | Expanding | 主动扩张 | 建议尺寸仅是明智的建议,但控件基本不采用。这个模式也是能屈能伸,但它倾向于主动扩张,尽可能占据新增的区域 | | Ignored | 野蛮扩张 | 忽略建议尺寸,虽然能屈能伸,但是它会尽最大可能占据空间 |
例子:
- 如果两个控件在一个水平箱式布局管理中,一个策略为
Preferred
,另一个为Expanding
或MinimumExpanding
,如果窗体水平拉伸,则Preferred
的大小不会改变,另一个会被拉伸。 - 如果,两个分别为
Expanding
和MinimumExpanding
,则两个都会被拉伸。 - 如果,两个都为
Fixed
,则控件间的间隙会被拉伸 - 关于压缩,如果达到了
minimumSizeHint
是不会被继续缩小了,但是Ignored
是会忽略sizeHint
和minimumSizeHint
的,所以会继续被压缩。
5. 伸缩性
在 QLayout 中提供了一个和控件大小策略相关的属性, layoutStretch 布局伸缩性,这个值是一个比例,如果布局中有三个控件,则三个是控件的占比,用逗号分隔,如: 1,1,1
只有会被压缩或拉伸的控件,才会受到该属性值影响(如 Fixed
是不会受该属性影响)
如果设置了伸缩性的比例值(如果都为0,则表示不设置)刚刚上面提到的大小策略的优先级将会被忽略
例子:
- 如果两个控件在一个水平箱式布局管理中,一个策略为
Preferred
,另一个为Expanding
,设置水平箱式布局的layoutStretch
为2,1
,则拉伸时,并不会像刚刚所说,只有Expanding
的会被拉伸,而是都会被拉伸,按照 2:1 的拉伸比例拉伸。
6. 窗体大小约束策略
Qlayout 的 layoutSizeConstraint
属性,用来约束窗体大小,只影响窗体,所以该属性只对最顶级的 QLayout 起作用
QLayout::SetDefaultConstraint
: 窗体最小值被设置为 minimumSize 值无法再缩小,如果 QLayout 内控件有更大的 minimumSize,则会取更大的 minimumSizeQLayout::SetNoConstraint
: 窗体没有约束策略QLayout::SetFixedSize
: 窗体大小被设定为 sizeHint 的大小,无法改变QLayout::SetMinimumSize
: 窗体最小为 minimumSize 无法再缩小,如果 QLayout 内控件有更小的 minimumSize,则会取更小的 minimumSize,总结就是,和 Default 不同的地方就是尽可能的小QLayout::SetMaxmumSize
: 同理,窗体最大值为 MaxmumSize,无法再放大QLayout::SetMinAndMaxSize
: 窗体最小为 minimumSize 无法再缩小,窗体最大值为 maxmumSize,无法再放大
7. contentsMargin
四个边距,布局内的控件或子布局距离该布局四个边的距离。
layoutLeftMargin
:layoutRightMargin
:layoutTopMargin
:layoutBottomMargin
:
layoutSpacing
为该布局内部控件之间的距离