QT之QML布局总结
一.手动定位
设置x,y的值
特点:常用于静态页面
二.锚定位
1.使用比较多,性能较好
anchors属性分为三部分:anchorLine margin offset
(1).anchorline
是anchors布局的基础,anchorline、bottom、
left、right、horizontalCenter、verticalCenter和baseline七条。
一个元素的AnchorLine和另外一个元素的AnchorLine进行对齐
(2).margin
margin分为topMargin bottomMargin leftMargin rightMargin,分别表示上下左右的边距
(3).offset
anchors布局有七条anchorline,margin有四个,四个margin对应四个anchorline,
另外的三个anchorline还需要进一步调整,这就是offset的作用,offset有horizontalCenterOffset、
verticalCenterOffset和baselineOffset
(4).其他特殊属性
anchors.fill和anchors.centerIn,分别表示填满元素和在元素中居中。两个属性的取值是Item
子元素宽度:childrenRect.width
2.关于显示模型可参考CSS盒子模型理解:
锚定位的常见属性如下:
三.布局定位器
锚布局需要一个个地去设置元素的anchors属性,而布局定位器可以很方便地排列多个元素,从而更方便的管理子项的位置。布局定位器是一种容器元素,专门用来管理界面中的其他元素。定位器不会改变它管理的元素的大小,与你使用 Qt Widgets 中的布局管理器的不同,如果希望使用 “自动根据界面尺寸变化调整孩子们的尺寸” 这种特性,可以使用 Qt Quick 中的布局管理器。
1.Row(行定位器)
其子控件宽度或高度为0,则该子控件将不会布局,并且在行中也不可见。 由于行自动将其子项水平放置,因此行中的子项不应设置其x位置,也不应使用left,right,anchor.horizontalCenter,fill或centerIn锚点水平锚定自身。 如果需要执行这些操作,请考虑在不使用Row的情况下放置项目。请注意,“行”中的项目可以使用“定位器”附加属性来访问有关其在“行”中位置的更多信息。当然,在Row中使用锚布局也是可以的,但是只是官方文档不建议这样子,因为这样子没有太大的意。Row 本身是一个 Item ,所以你可以使用锚布局来定位一个 Row。Row 有一个 spacing 属性,用来指定它管理的 Item 之间的间隔。还有一个 layoutDirection 属性,可以指定布局方向,取值为 Qt.LeftToRight 时从左到右放置 Item ,这是默认行为,取值为 Qt.RightToLeft 时从右向左放置 Item。一旦把一个 Item 交给 Row 来管理,那就不要再使用 Item 的 x 、 y 、 anchors 等属性了, Row 会安排得妥妥的。在一个 Row 内的 item,可以使用 Positioner 附加属性来获知自己在 Row 中的更多位置信息。 Positioner 有 index 、 isFirstItem 、 isLastItem 三个属性。
2.Column(列定位器)
Column 与 Row 类似,不过是在垂直方向上安排它的子 Items 。Column 本身也是一个 Item ,可以使用 anchors 布局来决定它在父 Item 中的位置。 Column 的 spacing 属性描述子 Item 之间的间隔。
3.Grid(网格定位器)
Grid 在一个网格上安置它的子 Items ,它会创建一个拥有很多单元格的网格,足够容纳它所有的子 Items 。Grid 会从左到右、从上到下把它的子 items 一个一个塞到单元格里。 item 默认会被放在一个单元格左上角 (0, 0) 的位置。你可以通过 rows 和 columns 属性设定表格的行、列数。如果你不设置,默认只有四列,而行数则会根据实际的 item 数量自动计算。rowSpacing 和 columnSpacing 指定行、列间距,单位是像素。Grid 的 flow 属性描述表格的流模式,可以取值 Grid.LeftToRight ,这是默认模式,从左到右一个挨一个放置 item,一行放满再放下一行;取值为 Grid.TopToBottom 时,从上到下一个挨一个放置 item,一列放满再放下一列。horizontalItemAlignment 和 verticalItemAlignment 指定单元格对齐方式。默认的单元格对齐方式和 layoutDirection 以及 flow 有关。
4.Flow(流式定位器)
Flow 其实和 Grid 类似,不同之处是它没有显式的行、列数,它会计算自身尺寸和子 item 尺寸来根据需要折行。它的 flow 属性,默认取值 Flow.LeftToRight ,从左到右安排 item ,直到 Flow 本身的宽度被超出时折行;当 flow 取值 Flow.TopToBottom 时,从上到下安排 item ,直到 Flow 本身的高度被超出时开始在下一列上安排 item 。spacing 属性描述 item 之间的间隔。
5.Repeater(中继器)重复元素
通常与定位器一起使用。工作方式像for循环与迭代器模式一样。Repeater有一个模型和一个委托:对于模型中的每个条目,委托都在一个以模型数据为种子的上下文中实例化。中继器项目通常包含在定位器类型(如行或列)中,以直观地定位中继器创建的多个委托项目。删除或动态销毁由Repeater创建的项会导致不可预知的行为。Positioner:定位器类型的对象附着到列、行、流或网格中的顶级子项。它提供的属性允许子项确定其在其父项“列”、“行”、“流”或“网格”的布局中的位置
示例:
import QtQuick 2.0
Rectangle{
id:root;
width: 252;
height: 252;
property variant colorArray: ["#00dbe3", "#67bde3", "#ea7025"];
Grid{ // Row、Column、Flow
anchors.fill: parent;
anchors.margins: 8;
spacing: 4; // 间隔
Repeater{
model: 16; // 子项目个数
Rectangle{
width: 56;
height: 56;
property int colorIndex: Math.floor(Math.random()*3); // Math.floor(Math.random()*3)生成0~2的随机数
color: root.colorArray[colorIndex];
border.color: Qt.lighter(color);
Text {
anchors.centerIn: parent;
color: "#f0f0f0";
text: "Cell " + index
}
}
}
}
}
四.布局管理器
布局管理器是从Qt5开始引入的功能,它的功能比定位器更强大,适合比较复杂的情景,传统的定位器,当窗口或控件发生变化时,控件大小并不能自动适应窗口变化,而布局管理器则可以实现自适应的功能。 Qt Quick 中的布局管理器与 Qt Widgets 中的相似,它与定位器的不同之处在于:布局管理器会自动调整子 Item 的尺寸来适应界面大小的变化。布局管理器的常见属性如下所示:
1.重点说明:
布局管理器使用时,布局负责分配其子Items的几何形状, 因此不应指定子Items的width, height, x, y或其他任何可能影响布局的因素(如anchors等),否则会产生冲突,
导致布局的结果具有不确定性。如果子Item也是布局, 也同样要遵循这个原理. 因此,只有没有父布局的布局才能具有“anchors.fill:parent;”。Layout types允许如下操作:
(1)设置文本和其他项目的对齐方式
(2)自动调整和填充分配的应用程序区域
(3)设置尺寸限制,例如最小或最大尺寸
(4)设置布局内项目之间的间距
2.布局管理器类型
RowLayout(行布局管理器)
ColumnLayout(列布局管理器)
GridLayout(网格布局管理器)
其他:弹簧功能
3.定位器和布局管理器的区别
(1)QML 中的布局管理器和QWidget的效果相似,与定位器不同的是,布局管理器会自动调整子Item的尺寸来适应界面大小的变化。定位器位器单单把元素组织在一起,并不会根据界面大小,自动调节孩子们的尺寸。
(2)QML里的定位器管理位置(x,y属性),而布局器还会管理项目宽高
五.qml 如何设置窗口大小为自适应
import QtQuick 2.0
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: Screen.width * 0.8 // 设置窗口宽度为屏幕宽度的80%
height: Screen.height * 0.8 // 设置窗口高度为屏幕高度的80%
// 或者也可以将width和height属性设置为父级元素的宽高,实现相对布局
// width: parent.width * 0.8
// height: parent.height * 0.8
}