QML是一种声明性语言,用于描述应用程序的用户界面。QML可以将用户界面分解,也可以将界面元素组合为组件。 QML描述了这些用户界面元素的外观和行为。 支持JavaScript来丰富此用户界面描述,以提供简单或复杂的逻辑。
一、qml基本语法和属性
举个例子来说明qml的基本语法,语法见注释
import QtQuick 2.14//导入模块以及模块的具体版本
import QtQuick.Window 2.14
Rectangle {//界面的根元素,每个qml文件必须得有根元素
id: root//根元素的名字叫root,所有qml文件的根的id最好都叫root,别叫别的名字
// properties: <name>: <value>
width: 120; height: 240//根元素宽高的初始尺寸
color: "#4A4A4A"//根元素的颜色属性,除了可以用颜色的色号,还可以用颜色的单词,比如red
//元素的属性的格式都是name:value(属性名:属性值)
Image {
id: triangle
x: (parent.width - width)/2; y: 40//元素可以嵌套,父元素可以通过id访问,也可以通过parent关键字访问
source: 'triangle_red.png'
}
Text {
id:text
y: triangle.y + triangle.height + 20//可以通过id的值访问qml中的任意元素
// reference root element
width: root.width//通过root名字访问根的宽度
color: 'white'
horizontalAlignment: Text.AlignHCenter
text: 'Triangle'
}
}
运行效果如下
horizontalAlignment用来设置文本的水平方式。horizontalAlignment的有效值为Text.AlignLeft,Text.AlignRight,Text.AlignHCenter和Text.AlignJustify。 verticalAlignment的有效值为Text.AlignTop,Text.AlignBottom和Text.AlignVCenter。
1.qml的属性
元素通过名字进行声明,但是元素通过属性或创建自定义属性来具体定义。属性是简单的键值对。属性有明确的类型,并且可以有初始值。例如
id: root//根元素的名字属性叫root,所有qml文件的根的id最好都叫root,别叫别的名字 width: 120; height: 240//根元素宽高的初始尺寸的值 color: "#4A4A4A"//根元素的颜色属性,除了可以用颜色的色号,还可以用颜色的单词,比如red
属性示例
Text {
// (1) identifier
id: thisLabel
//id是一个非常特殊的属性,用于引用QML文件中的元素。 id不是字符串类型,id是标识符和QML语法的一部分。 id在QML文件中必须是唯一的,并且不能被重置为其他值,也无法查询。
// (2) set x- and y-position
x: 24; y: 16
//属性的值取决于其类型。 如果没有为属性指定任何值,则属性值被置为初值。 有关属性初始值的更多信息需要查阅特定元素的文档
// (3) bind height to 2 * width
height: 2 * width
// 一个属性可以依赖一个或多个属性。 这称为属性的绑定。 当依赖的属性改变时,将更新绑定属性。高度值依赖宽度,高度终是宽度的两倍。
// (4) custom property
property int times: 24
//当添加自定义属性时,格式如下:property type name: value,property int times: 24就是自定义属性
// (5) property alias
property alias anotherTimes: thisLabel.times
//声明属性的另一种重要方法是使用alias关键字(property alias <name>: <reference>)alias关键字可以将对象属性或对象本身扩展到外部。 属性别名不需要类型,它使用引用属性或对象的类型。
//anotherTimes就是thisLabel.times的别名
// (6) set text appended by value
text: "Greetings " + times
//text属性中的int值将自动转换为字符串类型。 text属性也依赖于time属性。和time属性绑定,每次time属性更改时,文本都会更新。
// (7) font is a grouped property
font.family: "Ubuntu"
font.pixelSize: 24
//有些属性叫分组属性(就是属性里面还有属性,类似于C++的class或者struct)
//分组属性的另一种写法是font{family:" Ubuntu"; pixelSize:24}
// (8) KeyNavigation is an attached property
KeyNavigation.tab: otherLabel
//一些属性附加到元素本身(例如键盘输入)。 写法是<Element>.<property>:<value>。
// (9) signal handler for property changes
onHeightChanged: console.log('height:', height)
//对于每个属性,都可以提供信号处理程序。 属性更改后将调用此处理程序。在这里高度变化时将消息打印出来。
// focus is need to receive key events
focus: true
// change color based on focus value
color: focus?"red":"black"
}
运行效果如下
此外,qml还支持JS,示例如下
Text {
id: label
x: 24; y: 24
// custom counter property for space presses
property int spacePresses: 0
text: "Space pressed: " + spacePresses + " times"
// (1) handler for text changes
onTextChanged: console.log("text changed to:", text)
//文本更改处理程序onTextChanged每次按下空格键都会打印text
// need focus to receive key events
focus: true
//当按下空格键时,将调用JavaScript函数increment。
// (2) handler with some JS
Keys.onSpacePressed: {
increment()
}
//当按下esc键时,将清空text
// clear the text on escape
Keys.onEscapePressed: {
label.text = ''
label.spacePresses=0
}
// (3) a JS function
function increment() {//JS函数定义
label.spacePresses += 1
label.text = "Space pressed: " + spacePresses + " times"
}
}
二、基本的元素
元素可以分为可视元素和非可视元素。 可视元素(如Rectangle)具有几何形状,通常在屏幕上显示一个区域。 非可视元素(如Timer)通常用于操纵可视元素。
基本的可视元素包括Item,Rectangle,Text,Image和MouseArea等。通过使用Qt Quick Controls 2模块,可以创建由标准平台组件(例如按钮,标签和滑块)构建的用户界面。
1.Item元素
Item是所有可视元素的基础,因为所有其他视觉元素都是从Item继承的。Item本身不绘制任何内容,而是定义了所有可视元素的所有共有属性。正因如此,Item元素通常用作其他元素的容器
2.Rectangle
Rectangle扩展Item并为其添加填充颜色。另外,它支持由border.color和border.width定义的边框。如果要创建圆角矩形,可以使用radius属性。注意:未设置宽度/高度的矩形将不可见。
示例
Item {
id: root
width: rect1.width+rect2.width+50
height: rect1.height+50
Rectangle {
id:rect1
x:12
y:24
width: 320
height: 240
color: "blue"
}
Rectangle {
id:rect2
x:rect1.x+rect1.width+20
y:rect1.y
width: rect1.width
height: rect1.height
border.color: "blue"//分组元素
border.width: 3
radius: 3
}
}
还可以在rect1的color属性下面添加如下代码,使得左侧举行变成红边并且由蓝色渐变为灰色
gradient: Gradient {
GradientStop {
position: 0
color: "blue"
}
GradientStop {
position: 1
color: "gray"
}
}
border.color: "red"
梯度由一系列梯度停止点定义。 每个停止点都有位置(位置是一个浮点数,意味着可以添加多个位置)和颜色(字符串)。 本例中,位置标记了y轴方向上的位置(0 =顶部,1 =底部)。 color标记该位置的颜色。
再添加一个位置和颜色
GradientStop {
position: 0.5
color: "red"
}
效果如下
3.Text
Text元素用来显示文本,类型是字符串类型。Text元素根据字符串文本和使用的字体计算Text的初始宽度和高度。 可以使用字体分组属性(例如font.family,font.pixelSize,...)来改变Text。 要更改Text的颜色,只需使用color属性。
示例
Text {
id: name
width: 320
height: 240
x:width/2-50
y:height/2-50
text: qsTr("text example")
color: "pink"
font.family: "ubuntu"
font.pixelSize: 20
}
可以使用horizontalAlignment和verticalAlignment属性将Text对齐。 可以使用style和styleColor属性进一步增强文本渲染。
对于较长的Text的省略号效果,可以使用elide属性来实现显示。elide属性允许将省略号的位置设置为文本的左侧,右侧或中间(仅在宽度被设置时有效)。 如果不想看到省略号,想查看全文本,可以使用wrapMode属性来包装文本(仅在宽度被设置时有效)
elide可以是:Text.ElideNone(默认)、Text.ElideLeft、Text.ElideMiddle、Text.ElideRight
示例
Text {
id: name
width: 320
height: 240
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: qsTr("text example: a very long text")
color: "pink"
font.family: "ubuntu"
font.pixelSize: 30
elide: Text.ElideMiddle
style: Text.Sunken
styleColor: "black"
wrapMode: Text.WordWrap
}
此时,即使设置elide: Text.ElideMiddle,省略号也不会出现,因为设置了wrapMode: Text.WordWrap,wrapMode属性用于文本换行(仅在宽度被设置时有效)。 wrapMode可以是以下之一:
Text.NoWrap(默认)-不执行任何换行。 Text.WordWrap-仅在单词边界上进行换行。 Text.WrapAnywhere-换行在一行的任何一点完成,即使它发生在单词的中间。Text.Wrap-如果可能的话,换行发生在单词边界处; 否则,它将出现在行中的适当点,即使是在单词中间。
将wrapMode: Text.WordWrap去掉后的效果如下
4.Image
Image元素能够显示各种格式的图像。其中,source属性显示Image的路径(可以是带有斜杠的本地路径,也可以是图片链接),当源图像的大小与项目大小不同时,fillMode属性用来调整图片的大小。
Image.Stretch-图像缩放以适合、Image.PreserveAspectFit-图像均匀缩放以适合裁剪、Image.PreserveAspectCrop-图像均匀缩放以填充,必要时进行裁剪
示例
Image {
id: img1
source: "./triangle_red.png"
width: img1.width
height: img1.height
verticalAlignment: verticalCenter
horizontalAlignment: horizontalCenter
fillMode: Image.PreserveAspectCrop
clip: true
}
使用PreserveAspectCrop的图像元素还应该启用clip,以避免在图像边界之外渲染图像。 默认情况下,clip:false。
当fillMode: Image.PreserveAspectCrop和clip: true时,将窗口拖大后,图片会被剪切,如果不设置 fillMode: Image.PreserveAspectCrop和clip: true,图片则会自动缩小
5.MouseArea
为了与其他元素交互,通常会设置一个MouseArea。 MouseArea是一个不可见的矩形,可以在该矩形中捕获鼠标事件。当用户与可视部件交互时,鼠标区域会执行响应程序。
示例
Item {
id: root
width: 320
height: 240
Rectangle {
id:rect1
x:10
y:10
width: root.width/2-25
height: root.height-25
color: "red"
MouseArea {
id:mousearea
width: parent.width
height: parent.height
onClicked: rect2.visible =!rect2.visible
}
}
Rectangle {
id:rect2
x:rect1.width+rect1.x+20
y:rect1.y
width: rect1.width
height: rect1.height
border.color: "blue"
border.width: 5
radius: 4
}
}
参考
《qml book》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出