1. 布局系统的功能

在 Qt 中,布局系统可以完成:

  • 定位子控件
  • 得知窗体默认大小
  • 得知窗体最小大小
  • 窗体大小变化时进行布局排版
  • 内容改变(字体大小,隐藏,显示,移除等)时进行布局排版

2. 布局系统的结构

Qt 提供了 QLayout 类及其子类来为界面进行排版布局,结构如下:

  1. QObject QLayoutItem
  2. |______________|
  3. |
  4. QLayout
  5. _________________|__________________
  6. | | | |
  7. QBoxLayout QFormLayout QGridLayou QStackedLayout
  8. ______|_______
  9. | |
  10. QHBoxLayout QVBoxLayout

QLayout 是布局系统中的抽象类,继承自 QObject 和 QLayoutItem,其中四个子类为:

  • QBoxLayout(箱式布局)
  • QFormLayout(表单布局)
  • QGridLayout(网格布局)
  • QStackedLayout(栈布局)

3. 控件大小

对于控件大小,最重要的两个属性是 sizeHintminimumSizeHint,这是 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,另一个为 ExpandingMinimumExpanding,如果窗体水平拉伸,则 Preferred 的大小不会改变,另一个会被拉伸。
  • 如果,两个分别为 ExpandingMinimumExpanding,则两个都会被拉伸。
  • 如果,两个都为 Fixed,则控件间的间隙会被拉伸
  • 关于压缩,如果达到了 minimumSizeHint 是不会被继续缩小了,但是 Ignored 是会忽略 sizeHintminimumSizeHint 的,所以会继续被压缩。

5. 伸缩性

在 QLayout 中提供了一个和控件大小策略相关的属性, layoutStretch 布局伸缩性,这个值是一个比例,如果布局中有三个控件,则三个是控件的占比,用逗号分隔,如: 1,1,1

只有会被压缩或拉伸的控件,才会受到该属性值影响(如 Fixed 是不会受该属性影响)

如果设置了伸缩性的比例值(如果都为0,则表示不设置)刚刚上面提到的大小策略的优先级将会被忽略

例子:

  • 如果两个控件在一个水平箱式布局管理中,一个策略为 Preferred,另一个为 Expanding,设置水平箱式布局的 layoutStretch2,1,则拉伸时,并不会像刚刚所说,只有 Expanding 的会被拉伸,而是都会被拉伸,按照 2:1 的拉伸比例拉伸。

6. 窗体大小约束策略

Qlayout 的 layoutSizeConstraint 属性,用来约束窗体大小,只影响窗体,所以该属性只对最顶级的 QLayout 起作用

  • QLayout::SetDefaultConstraint: 窗体最小值被设置为 minimumSize 值无法再缩小,如果 QLayout 内控件有更大的 minimumSize,则会取更大的 minimumSize
  • QLayout::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 为该布局内部控件之间的距离