前言
QT Quick中布局一般有如下四种方式,
- 绝对定位:x、y、z、width、height
- 锚定位(anchors、相对定位)
- 定位器(Row、Column、Grid、Flow)
- 布局管理器(RowLayout、ColumnLayout、GridLayout、StackLayout)
绝对布局很好理解,给值就显示,但是不灵活;
anchors 实际上是 Item 的一个属性集
Row 则是一个单独的 Item ,专门用来管理其它 Item 的,后面介绍的几种布局,也是类似的。
锚(anchors) 布局的参数:
1 | //左上右下对齐 |
其中
- real 具体的数值
- Item是组建的ID或者parent
- bool是true或false
- AnchorLine 示例
anchors.horizontalCenter: parent.horizontalCenter
注意
不要在Row或RowLayout相关的组件中使用anchors,会导致组件本身的特性不生效。
使用场景
- 在
Item和Rectangle中的组件我们可以使用绝对定位和锚定位 定位器和布局管理器中自动定位的方向不要使用绝对定位和锚定位,比如Column的子组件就不要设置y。定位器中没有类似margin和padding的功能,我们可以使用spacing来调整间距,如果间距不固定,可以使用Item组件占位。布局管理器相当于flex布局,子组件使用Layout.xxx来调整位置
定位组件和布局管理器
定位器(Row、Column、Grid、Flow)
布局管理器(RowLayout、ColumnLayout、GridLayout、StackLayout)
Layout
要使用layout布局的属性 需要引用
1 | import QtQuick.Layouts 1.15 |
简单示例
横向分布,最后一个填充剩余空间。
1 | import QtQuick 2.15 |
显示效果
其中
1 | RowLayout { |
和
1 | RowLayout { |
是等效的,前者就用了锚(anchors) 布局
只有在Layout相关的控件中才能使用Layout.fillWidth: true相关的属性。
所以RowLayout可以实现元素填充剩余空间,而Row是不可以的,除非我们复制宽度是通过计算的值。
代码如下
1 | import QtQuick 2.15 |
属性设置
注意
Layout中不要用
anchors来设置了,是无效的。
Margin
1 | Image { |
或者
1 | Image { |
宽高
在RowLayout和ColumnLayout中,子组件的宽高就无效了
宽高由Layout.preferredWidth、Layout.preferredHeight、Layout.fillWidth、Layout.fillHeight决定
1 | Image { |
对齐
Layout.alignment 属性允许你指定子项在布局中的对齐方式。
你可以使用 Qt.AlignLeft、Qt.AlignRight、Qt.AlignTop、Qt.AlignBottom、Qt.AlignHCenter、Qt.AlignVCenter 等常量来设置对齐方式。
Layout.fillWidth 是一个属性,用于控制子项是否应该扩展以填充其父布局的宽度。
具体来说,当你在使用 GridLayout、RowLayout 或 ColumnLayout 等布局时,可以为子项设置 Layout.fillWidth 属性,以决定子项是否应该水平拉伸以填充可用空间。
Layout.fillWidth: true:这会使子项的宽度扩展以匹配父布局的宽度。也就是说,子项会尽可能地变宽,以填满父布局中分配给它的空间。Layout.fillWidth: false:这是默认值,子项将保持其自然宽度,不会扩展以填充父布局的宽度。
Column和ColumnLayout
在 Qt Quick 中,Column 和 ColumnLayout 都是用来将子项垂直排列的容器类型,但它们在实现方式和使用场景上有一些区别。
对比
Column
- 基本用法:
Column是一个简单的垂直布局容器,它会按照子项的默认大小将它们垂直排列。 - 子项大小:子项的大小不受
Column的影响,子项会保持它们的默认大小或设置的显式大小。 - 隐式大小:
Column的隐式高度是所有子项总高度的和,隐式宽度是所有子项中最大宽度的值。 - 布局调整:
Column不会自动调整子项的大小,子项的大小由它们自己控制。
ColumnLayout
基本用法:
ColumnLayout是一个更强大的垂直布局容器,它提供了一些布局管理功能,可以自动调整子项的大小。子项大小:子项可以使用布局属性(如
Layout.preferredHeight和Layout.preferredWidth)来指定它们的首选大小。ColumnLayout会根据需要调整子项的大小,以适应容器的大小。隐式大小:
ColumnLayout的隐式高度和宽度取决于子项的布局属性和内容。布局调整:
ColumnLayout可以自动调整子项的大小,以适应容器的大小,提供了更多的布局灵活性。
简单来说
ColumnLayout等Layout组件和css中的flex类似,子组件会自动适应宽高。
Column等定位组件的子组件则完全取决于自己的属性。
在Row和Column中,子组件的宽高是由自己的宽高决定
1 | Image { |
在RowLayout和ColumnLayout中,子组件的宽高就无效了
宽高由Layout.preferredWidth、Layout.preferredHeight、Layout.fillWidth、Layout.fillHeight决定
1 | Image { |
示例
Column 示例
1 | import QtQuick 2.15 |
ColumnLayout 示例
1 | import QtQuick 2.15 |
居中示例
Row
1 | Row { |
RowLayout
1 | RowLayout { |
总结
Column适用于简单的垂直排列场景,子项大小由它们自己控制。ColumnLayout适用于需要更复杂布局管理的场景,可以自动调整子项的大小。
上下重叠
Item 中的子组件默认不会自动填充整个 Item 的空间,它们的尺寸和位置由自身的属性决定。
如果希望子组件自动填充Item,可以使用以下方法:
- 使用
anchors.fill: parent让子组件填充整个Item。 - 直接设置子组件的
width和height为父Item的尺寸。
这两种方法都可以让子组件自动填充父 Item 的区域。
1 | Item { |
可滚动容器
1 | ScrollView { |
Item和Rectangle的区别
Item:它是 QML 中所有可视元素的基类,是最基础的可视元素,具备位置、大小、变换等基础属性,但没有默认的外观表现。
也就是说,单纯创建一个
Item实例时,在界面上是看不到它的。Rectangle:继承自
Item,这意味着它拥有Item的所有属性,同时还有自身特有的属性,比如
color(填充颜色)、border(边框)、radius(圆角)、clip(内部剪裁)等,默认会以矩形的形状显示在界面上。
比如
1 | Rectangle { |