一、组件
组件是可重用的元素,QML提供了不同的方式来创建组件。 最简单的组件是基于文件的组件。 通过在文件中放置QML元素并为该文件指定元素名称(例如Button.qml)来创建基于文件的组件。 然后导入该组件后,就可以像使用QtQuick模块中的其他元素一样使用该组件。组件文件的文件名的首字母开头一定要大写!!!
示例
//Button.qml
import QtQuick 2.12
Rectangle {
id:buttonsize
x:10
y:10
width:100
height:30
color: "red"
border.color: "blue"
property alias text: buttontext.text//自定义属性
signal clicked
Text {
id: buttontext
text: qsTr("button")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("mouseare clicked")
buttonsize.clicked()//触发clicked信号
}
}
}
Item {
id: root
width: 320
height: 240
Button {
id:button1
x:100
y:status.y-status.height-10
text: "Start"
onClicked: {
console.log("onclicked in main qml")
status.text = "Button clicked!"
}
}
Text {
id: status
text: qsTr("wait for pressing")//起始text
elide: Text.ElideMiddle
x:100
y:100
width: 150
height: 40
}
}
结果
上述代码在Button.qml中实现了一个组件button,在别的文件中,使用了该组件,当点击组件的mousearea时,会先触发组件的onclicked,并发出clicked信号,然后使用组件的文件中的onclicked相应该信号并修改text的状态,所以会先打印出qml: mouseare clicked,然后打印出qml: onclicked in main qml
组件类似于C++中的类。将类封装后,就可以使用类
二、元素几何变换
元素几何变换用于改变元素的几何形状。 QML可以对元素进行平移,旋转和缩放。x,y位置可以完成平移转换。 使用rotation属性实现旋转。 该值以度(0-360)为单位。 使用scale属性实现缩放,值<1表示元素按比例缩小,而值> 1表示元素按比例放大。 旋转和缩放不会更改几何形状。 x,y,width,height没有变。 只是绘画发生了变化。
示例
先定义一个图像组件
Image {
id: root
signal clicked
MouseArea {
id:mousearea
anchors.fill: parent
onClicked: {
root.clicked()
}
}
}
接着进行元素变换
Item {
id: root
Image {
id: bg
source: "./background.png"
}
width: bg.width
height: bg.height
MouseArea {
id:bgclicker
anchors.fill:parent
onClicked: {
circle.x=84
circle.y=84
box.rotation=0
triangle.scale=1
}
}
Clickedimg {
id:circle
x:84
y:68
source: "./circle_blue.png"
antialiasing: true
onClicked: {
x+=20
y+=20
}
}
Clickedimg {
id:box
x:164
y:68
source: "./box_green.png"
antialiasing: true
onClicked: {
rotation+=30
}
}
Clickedimg {
id:triangle
x:248
y:68
source: "./triangle_red.png"
antialiasing: true
onClicked: {
scale+=0.1
}
}
}
效果如下
其中的antialiasing: true用于抗锯齿
此外,当三个元素彼此覆盖时,圆在最下,方形在中间,三角形在最上,因为Z方向的顺序和元素的代码的出现顺序有关。在代码中较早出现的元素具有较低的堆叠顺序(称为z方向顺序)。 z顺序也可以通过Item的z属性进行操作。鼠标区域的堆叠顺序也是如此。 在代码中较早出现的元素的鼠标区域将会被后出现的元素的鼠标区域覆盖。
三、元素的定位
定位器用来给qml元素进行位置锁定。QtQuick模块提供的定位器有Row, Column, Grid和Flow
示例
先实现三个颜色为红绿蓝的方块组件,代码如下
//Redsquare.qml
import QtQuick 2.0
Rectangle {
id:redsquare
width: 50
height: 50
color: "red"
border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}
//Bluesquare.qml
import QtQuick 2.0
Rectangle {
id:redsquare
width: 50
height: 50
color: "blue"
border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}
//Greensquare.qml
import QtQuick 2.0
Rectangle {
id:redsquare
width: 50
height: 50
color: "green"
border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}
上述三个组件只不过颜色不同,其他完全相同,组件实现完后,分别演示四种定位器
1.Row
Rectangle {
id:root
width: 320
height: 240
Row {
id:row
anchors.centerIn: parent
spacing: 15//控制元素的间距
Redsquare {}
Bluesquare {}
Greensquare {}
}
}
2.Column
Rectangle {
id:root
width: 320
height: 240
Column {
id:col
anchors.centerIn: parent//元素位于父元素的中央位置
spacing: 15
Redsquare {}
Bluesquare {
width: 100
}
Greensquare {}
}
}
定位器Row和Column的代码几乎都是一样的,Grid的代码略有不同;Grid通过设置rows和columns属性将元素排列在网格中。 如果不设置columns或rows,则根据columns或rows数量来计算另一个。 例如,将行设置为3并添加6个元素,那么列将自动为2。 属性flow和layoutDirection用于控制元素添加到Grid的顺序,而spacing还是控制元素的间距。
3.Grid
Rectangle {
id:root
width: 320
height: 240
Grid {
id:grid
anchors.centerIn: parent
spacing: 10
columns: 2
rows: 2
Redsquare {}
Redsquare {}
Redsquare {}
Redsquare {}
}
}
4.Flow
Flow将元素添加到流中。 使用flow和layoutDirection属性元素的排列的方向。这样,元素可以横向或者纵向排列。将元素添加到流中时,可以根据需要,将它们包装起来形成新的行或列。 为了使Flow工作,必须具有宽度或高度。 可以直接通过属性设置,也可以通过锚定布局设置。
示例
Rectangle {
id:root
width: 320
height: 240
Flow {
anchors.fill: parent
anchors.margins: 20
spacing: 10
flow: Flow.LeftToRight
//flow: Flow.TopToBottom
Redsquare{}
Bluesquare {}
Greensquare {}
Redsquare {}
}
}
flow属性如果不设置的话,默认就是Flow.LeftToRight,可以设置为Flow.TopToBottom,效果如下
其中的margin是关于布局的,后面再说
上述代码最多只添加了四个元素,但是,如果要添加100个元素总不能一个一个敲吧?和定位器经常一起使用的元素是Repeater。 Repeater类似一个for循环。 在最简单的情况下,Repeater只是通过model属性提供循环次数
示例
Rectangle {
id:root
width: 250
height: 250
property var colorarray: ["red", "green", "blue"]
Grid {
id:grid
anchors.fill: parent
anchors.margins: 15
spacing: 5
Repeater {
model: 16
Rectangle {
width: 50
height: 50
property int colorindex: Math.floor(Math.random()*3)
color: root.colorarray[colorindex]
border.color: Qt.lighter(color)
Text {
id: name
text: qsTr("ceil")+index
color: "white"
anchors.centerIn: parent
}
}
}
}
}
对于每个循环,Repeater都会创建一个方块。 在方块中,通过JS的函数Math.floor(Math.random()* 3)选择颜色。 Math.random()的返回值是一个大于等于0小于1的随机数,所以floor(Math.random()* 3)向下取整,提供了一个介于0-2之间的随机数,因此可以从颜色数组中选择颜色。 此外,循环时,Repeater将会生成index。 它包含当前的循环索引(0,1,.. 15)。
显示结果如下
参考
《qml book》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出