项目原因,用了一年的QML,对QML并不看好,Qt在大力的布局移动端,但是面对强大的android生态,难免有点弱小,但是在传统的PC端领域,仍然是个不错的选错。
现在对布局相关知识做一个梳理,涉及到的类有三种:
定位器:Row,Column,Grid,Flow
布局管理器:RowLayout,GridLayout,ColumnLayout
锚:anchors
定位器
- Row(行):它的子对象从左到右,或者从右到左依次排列,排列方式取决于 layoutDirection属性。spacing属性用来设置每个元素之间的间隔大小。
- Column(列):它的子对象通过顶部对齐的列方式进行排列。spacing属性用 来设置每个元素之间的间隔大小。
- Grid(栅格):元素通过设置rows(行数)和columns(列数)将子对象排列在一个 栅格中。可以只限制行数或者列数。如果没有设置它们中的任意一个,栅格元素会 自动计算子项目总数来获得配置,例如,设置rows(行数)为3,添加了6个子项目 到元素中,那么会自动计算columns(列数)为2。
- Flow(流): 与Grid类似不同之处在于,不用指定行数和列数,他会计算Item的尺寸然后与自身尺寸比较自动换行。
- 通常Repeater(重复元素)与定位器一起使用。它的工作方式就像for循环与迭代器 的模式一样
- 上面的几个编辑器都具有如下属性:add、move、populate
- 都具有Positioner的附加属性,可以通过Positioner的index、isFirstItem、isLastItem获取当前显示Item的信息。
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
color: "black"
//列
Column{
anchors.left: parent.left
spacing: 10 //间隔
Repeater {
model: 4
Rectangle {
width: 50
height: 50
color: getRectColor()
function getRectColor() {
if (Positioner.index === 0)
return 'red'
else if (Positioner.index === 1)
return 'yellow'
else if (Positioner.index === 2)
return 'blue'
else
return 'green'
}
}
}
}
//行
Row{
anchors.top: parent.top
anchors.right: parent.right
spacing: 10 //间隔
Repeater {
model: 4
Rectangle {
width: 50
height: 50
color: getRectColor()
function getRectColor() {
if (Positioner.index === 0)
return 'red'
else if (Positioner.index === 1)
return 'yellow'
else if (Positioner.index === 2)
return 'blue'
else
return 'green'
}
}
}
}
//栅格
Grid{
anchors.bottom: parent.bottom
anchors.right: parent.right
spacing: 10 //间隔
columns: 3 //三列
Repeater {
model: 4
Rectangle {
width: 50
height: 50
color: getRectColor()
function getRectColor() {
if (Positioner.index === 0)
return 'red'
else if (Positioner.index === 1)
return 'yellow'
else if (Positioner.index === 2)
return 'blue'
else
return 'green'
}
}
}
}
//流
Flow{
anchors.centerIn: parent
spacing: 10 //间隔
width: 200
Repeater {
model: 14
Rectangle {
width: 50
height: 50
color: getRectColor()
function getRectColor() {
if (Positioner.index === 0)
return 'red'
else if (Positioner.index === 1)
return 'yellow'
else if (Positioner.index === 2)
return 'blue'
else if (Positioner.index % 5 === 3)
return '#00FFFF'
else
return 'green'
}
}
}
}
}
布局管理器
布局管理器与Qt QWidget中的布局类似,与定位器布局的不同就是,布局管理器会自动调节界面的尺寸适应界面的大小。要使用布局管理器,需要导入Layout模块,常用的布局管理器有RowLayout、ColumnLayout和GridLayout
下面以RowLayout为例说明一下Layout的一些属性;
Layout.minimumWidth : 最小宽度
Layout.minimumHeight : 最小高度
Layout.preferredWidth: 参考宽度
Layout.preferredHeight : 参考高度
Layout.maximumWidth: 最大宽度
Layout.maximumHeight: 最大高度
Layout.fillWidth: 为true Item 宽度尽可能最大。false Item宽度为 参考宽度
Layout.fillHeight: 同Layout.fillWidth类似
Layout.alignment: Item的对齐方向对于GridLayout来讲,flow可以指定排列方式,rows和columns可以指定行数和列数,Layout.columnSpan所跨的列数,Layout.rowSpan所跨的行数
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
color: "black"
//行
RowLayout {
anchors.top: parent.top
anchors.topMargin: 5
anchors.left: parent.left
anchors.leftMargin: 5
width: 500
Rectangle {
color: 'red'
Layout.fillWidth: true //true 宽度 高度为最大宽度
Layout.minimumWidth: 50
Layout.preferredWidth: 100
Layout.maximumWidth: 200
Layout.minimumHeight: 200
}
Rectangle {
color: 'blue'
Layout.fillWidth: false //false 宽高 为参考的宽度
Layout.minimumWidth: 100
Layout.preferredWidth: 100
Layout.preferredHeight: 100
}
}
//列
ColumnLayout {
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
anchors.left: parent.left
anchors.leftMargin: 5
height: 300
Rectangle {
color: 'green'
Layout.fillHeight: true
Layout.minimumHeight: 50
Layout.preferredWidth: 200
Layout.preferredHeight: 100
Layout.maximumWidth: 250
Layout.maximumHeight: 200
}
Rectangle {
color: 'yellow'
Layout.fillHeight: false
Layout.minimumWidth: 100
Layout.preferredWidth: 100
Layout.preferredHeight: 120
}
}
//栅格
GridLayout {
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
anchors.right: parent.right
anchors.rightMargin: 5
flow: GridLayout.LeftToRight
height: 200
columns: 2 //2行2列
Rectangle {
color: 'red'
Layout.columnSpan: 2 //占 两列
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
width: 50
height: 50
}
Rectangle {
color: 'yellow'
width: 50
height: 50
}
Rectangle {
color: 'blue'
Layout.rowSpan: 2 //占 两行
width: 50
height: 50
}
Rectangle {
color: 'green'
width: 50
height: 50
}
}
}
锚
- 一个元素有6条锚定线(top顶,bottom底,left左,right右,horizontalCenter水平 中,verticalCenter垂直中)。
- 在文本元素(Text Element)中有一条文本的锚定基 线(baseline)。
- 每一条锚定线都有一个偏移(offset)值,在top(顶), bottom(底),left(左),right(右)的锚定线中它们也被称作边距。
- 对于 horizontalCenter(水平中)与verticalCenter(垂直中)与baseline(文本基线)中 被称作偏移值。
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 640
height: 480
color: "black"
Rectangle{
color: "white"
anchors.left: parent.left
anchors.leftMargin: 20
width: 100
height: 100
Rectangle {
color: 'red'
width: 48
height: 48
anchors.fill: parent //1. 元素填充它的父元素。
anchors.margins: 8
}
}
Rectangle{
color: "white"
anchors.right: parent.right
anchors.rightMargin: 20
width: 100
height: 100
Rectangle {
color: 'red'
width: 48
height: 48
anchors.left: parent.left //2. 元素左对齐它的父元素
anchors.leftMargin: 8
}
}
Rectangle{
color: "white"
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.left: parent.left
anchors.leftMargin: 20
width: 100
height: 100
Rectangle {
color: 'red'
width: 48
height: 48
anchors.horizontalCenter: parent.horizontalCenter//3. 元素中间对齐
}
}
Rectangle{
color: "white"
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.right: parent.right
anchors.rightMargin: 20
width: 100
height: 100
Rectangle {
color: 'red'
width: 48
height: 48
anchors.centerIn: parent // 4. 元素在它的父元素中居中
}
}
}