QML类型系统
基本类型
QML默认支持一些基本类型,使用它们时不需要import
语句。
下面是QML语言提供的基本类型:
类型 | 描述 |
bool | true/false,以二进制存储。 |
double | 带有小数点的数字,并以双精度IEEE浮点格式存储。 |
enum | 命名枚举值。 |
int | 整数,例如0、10或-20。取值范围为-2147483648至2147483647。 |
list | QML对象的列表。 |
real | 带小数点的数字,例如1.2或-29.8。以双精度IEEE浮点格式存储。 |
string | 带引号的自由格式文本字符串,例如“ Hello world!”。 |
url | 资源定位符。可以是相对路径,也可以是绝对路径。 |
var | 通用属性类型,可以引用任何数据类型。 |
小贴士:enum不能单独使用,必须结合其类型一起使用。list只能存储QML对象,而不能包含任何基本类型的值。
另外,QML的QtQuick模块也提供了一些基本类型:
类型 | 描述 |
color | 可以通过SVG颜色名称(如"red"或"blue")、十六进制字符串(如"#RRGGBB"或"#AARRGGBB")、Qt全局对象的方法(如Qt.rgba()或Qt.hsva())来进行引用。 |
date | 日期值(如"2020-12-31 23:59")。 |
font | 字体类型(如font.family)。 |
matrix4x4 | 一个4x4的矩阵类型,支持幂运算。可以使用Qt.matrix4x4()函数来组成此类型的值。 |
point | 具有x和y属性的类型(如"0, 20")。 |
quaternion | 具有scalar, x, y和z属性的类型(如"1, 10, 10, 1",Qt.quaternion(1, 10, 10, 1))。 |
rect | 具有x, y, width和height属性的类型(如"50, 50, 100x100",Qt.rect(50, 50, 100, 100))。 |
size | 具有width和height属性的类型(如"150x50",Qt.size(150, 50))。 |
vector2d | 二维向量类型。具有x和y属性(如"1, 2",Qt.vector2d(1,2);)。 |
vector3d | 三维向量类型。具有x、y和z属性(如"0, 1, 0",Qt.vector3d(0, 1, 0))。 |
vector4d | 四维向量类型。具有x、y、z和w属性(如"1, 2, 3, 4",Qt.vector4d(1,2,3,4);)。 |
示例如下:
property int count: 10
property double weight: 100.0
property string placeHolderText: "Hello QML"
property color backgroundColor: "#F7F7F7"
property size defaultSize: Qt.size(150, 50)
property rect defaultRect: Qt.rect(50, 50, 100, 100)
property vector2d defaultVector2d: Qt.vector2d(1,2)
property int count: 10
property double weight: 100.0
property string placeHolderText: "Hello QML"
property color backgroundColor: "#F7F7F7"
property size defaultSize: Qt.size(150, 50)
property rect defaultRect: Qt.rect(50, 50, 100, 100)
property vector2d defaultVector2d: Qt.vector2d(1,2)
对象类型
QML对象类型用于实例化QML对象。它通过指定类型名称后跟一组包含该对象属性的花括号来声明对象的类型。对象类型名称必须由字母、数字或下划线组成,并且以大写字母开头。使用它们时需要import
语句。每个QML文件都隐式定义了一个QML对象类型,该类型可以在其他QML文件中重复使用。
内置对象类型
QML提供了很多内置对象类型,如QtQuick模块中的Rectangle
、Text
、Image
、TextInput
等。QtQuick.Controls
模块中的Button
、Label
、CheckBox
、Page
等。
使用QML文件实现自定义对象类型
可以通过创建QML文件实现自定义QML对象类型。该文件名称同样必须由字母、数字或下划线组成,并且以大写字母开头。如下面创建一个SquareButton.qml文件:
// SquareButton.qml
import QtQuick 2.0
Rectangle {
property int side: 100
width: side; height: side
color: "red"
MouseArea {
anchors.fill: parent
onClicked: console.log("Button clicked!")
}
}
// SquareButton.qml
import QtQuick 2.0
Rectangle {
property int side: 100
width: side; height: side
color: "red"
MouseArea {
anchors.fill: parent
onClicked: console.log("Button clicked!")
}
}
这样就可以在与SquareButton.qml文件同级目录的其他QML文件中使用SquareButton
类型。
// myapplication.qml
import QtQuick 2.0
SquareButton {}
// myapplication.qml
import QtQuick 2.0
SquareButton {}
通过qmlscene
命令执行myapplication.qml文件,可以看到运行效果如下:
点击界面后,终端会有响应日志输出。
内联组件
有时,为一个类型创建一个新文件会很不方便。在这种情况下,可以使用内联组件来完成。内联组件是在QML文件中声明一个新组件。语法如下:
component : BaseType {// declare properties and bindings here
}
component : BaseType {// declare properties and bindings here
}
在声明内联组件的文件中,可以直接通过名称引用该类型。
// Images.qml
import QtQuick 2.15
Item {
component LabeledImage: Column {
property alias source: image.source
property alias caption: text.text
Image {
id: image
width: 50
height: 50
}
Text {
id: text
font.bold: true
}
}
Row {
LabeledImage {
id: before
source: "before.png"
caption: "Before"
}
LabeledImage {
id: after
source: "after.png"
caption: "After"
}
}
property LabeledImage selectedImage: before
}
// Images.qml
import QtQuick 2.15
Item {
component LabeledImage: Column {
property alias source: image.source
property alias caption: text.text
Image {
id: image
width: 50
height: 50
}
Text {
id: text
font.bold: true
}
}
Row {
LabeledImage {
id: before
source: "before.png"
caption: "Before"
}
LabeledImage {
id: after
source: "after.png"
caption: "After"
}
}
property LabeledImage selectedImage: before
}
如果在其他文件中引用该内联组件,则必须在其前面加上组件名称。
// LabeledImageBox.qml
import QtQuick 2.15
Rectangle {
property alias caption: image.caption
property alias source: image.source
border.width: 2
border.color: "black"
Images.LabeledImage {
id: image
}
}
// LabeledImageBox.qml
import QtQuick 2.15
Rectangle {
property alias caption: image.caption
property alias source: image.source
border.width: 2
border.color: "black"
Images.LabeledImage {
id: image
}
}
小贴士:内联组件不与声明它们的组件共享作用域,并且不可以嵌套使用。
JavaScript类型
QML可以支持JavaScript中的数据类型。如基本类型String
、Number
、Boolean
、Null
、Undefined
、Symbol
等。引用类型Object
、Array
、Function
、Date
等。
QML允许使用var
或let
语句在JavaScript表达式中声明一个变量,如下面的代码在QML中的JavaScript表达式里都是完全正常的:
var cars = new Array();
cars[0] = "Cat";
cars[1] = "Dog";
cars[2] = "Panda";
var cars = new Array();
cars[0] = "Cat";
cars[1] = "Dog";
cars[2] = "Panda";
var sum = function (num1, num2) {
return num1 + num2
}
console.log(sum(10, 20))
var sum = function (num1, num2) {
return num1 + num2
}
console.log(sum(10, 20))
小贴士:与QML不同,JavaScritp作为一种弱类型语言,它的变量是没有类型的,只有值才具有类型。变量可以随时持有任何类型的值。