每一个QML对象都定义了一系列属性,类似于C++中的成员变量,属性名的首字母一般小写,若属性名以多个单词表示,那么第二个及以后的单词,首字母大写。
id属性——
QML对象的id属性是唯一的,不同对象的id属性值不能相同,我们可通过某个对象的id属性来访问这个对象。id属性是QML语言内建的一个属性,在对象实例化完成后其值是不能被修改的,不同于其它的普通属性。id属性值必须以小写字母或下划线开头,且不能包含字母、数字、下划线以外的其它字符,如下所示:
Rectangle {
id: root
width: 800; height: 480
color: "lightblue"
Column {
Text { id: myText; text: "Hello World" }
Text { text: myText.text }
}
}
自定义属性——
在QML文件中我们可自定义属性,语法如下:
[default] property <propertyType> <propertyName> [ : <value> ]
自定义属性完成后会自动为这个属性创建一个属性值改变的信号和相应的信号处理器on<PropertyName>Changed,这里的ProperName是这个属性的名字,首字母大写,如下所示:
Rectangle {
id: root
property string someText
onSomeTextChanged: console.log("The someText will be: " + someText)
width: 800; height: 480
color: "lightblue"
MouseArea {
anchors.fill: parent
onClicked: someText = "click"
}
}
properName以一个小写字母开头,只能包括字母、数字和下划线。propertyType可以是QML基本类型,enumeration以int来代替,也可以是QML对象类型,神奇的var类型是返型的,支持任何类型的属性值,如下所示:
Item {
property int theNumber
property string theString
property url theUrl
property Item someItem
property Rectangle someRectangle
property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" }
}
属性值可以被初始化,也可以使用JavaScript表达式来赋值,通过这两种方式赋值时,可以是一个静态值,也可以是一个与其它属性绑定的值。
Rectangle {
id: rootRect
property color theColor: "green"
property color previousColor: rootRect.color
property color nextColor
width: 100; height: 100
color: "red"
Component.onCompleted: {
rootRect.nextColor = rootRect.color
console.log(theColor, previousColor, nextColor, rootRect.color)
}
}
属性是类型安全的,赋值时属性值必须与属性类型匹配,否则会出错,如下所示:
// Invalid property assignment: int expected
property int theNumber: "one"
列表属性——
先看如下代码:
Item {
children: [
Text { text: "textOne" },
Text { text: "textTwo" },
Text { text: "textThree" }
]
Component.onCompleted: {
for(var i = 0; i < children.length; i++)
console.log("text of lable", i, ":", children[i].text)
}
}
上面例子中的children属性就是一个列表属性,包含在一对方括号中,里面的元素必须是QML对象类型而不能是QML基本类型,并以逗号分隔。列表内的元素可通过数组下标[index]访问,元素个数由length属性提供。若列表内只有一个元素,方括号可省略。
自定义列表属性,代码如下:
Item {
property list<Rectangle> siblingRects
property list<Rectangle> childRects: [
Rectangle { color: "red" },
Rectangle { color: "green" },
Rectangle { color: "blue"}
]
Component.onCompleted: {
for(var i = 0; i < childRects.length; i++)
console.log("color of lable", i, ":", childRects[i].color)
}
}
分组属性——
在某些情况下,属性可以是由若干个子属性构成的一个逻辑组,我们可以用“.”符号或者分组符号对其进行赋值。
Text {
//dot notation
font.pixelSize: 12
font.bold: true
}
Text {
//group notation
font { pixelSize: 12; bold: true }
}
属性别名——
属性别名引用其它的属性,语法如下:
[default] property alias <name>: <alias reference>
name是我们自定以的属性名,aliasreference是属性别名所引用的那个属性或对象,也就是说属性别名可以引用自一个单一的属性,也可以引用自一个复杂的对象。属性绑定是动态的,但不是双向的,而通过属性别名可达到动态、双向的效果,即修改name和aliasreference中任一个的值,与之关联的另一个属性值也会随之改变。还有一点需要注意的是,如果属性别名与已有的属性名相同,就会把已有的属性覆盖掉,当我们再使用这个属性的时候,实际上使用的是我们自定义的那个属性,如下所示:
Rectangle {
id: rootRect
property alias color: blueRect.color
property alias theRect: blueRect
color: "red"
Rectangle {
id: blueRect
color: "#1234ff"
}
Component.onCompleted: {
console.log ("color:", color, // "#1234ff"
"blueRect.color:", blueRect.color, // "#1234ff"
"theRect.color:", theRect.color, // "#1234ff"
"rootRect.color:", rootRect.color) // "#1234ff"
color = "#884646"
console.log ("color:", color, // "#884646"
"blueRect.color:", blueRect.color, // "#884646"
"theRect.color:", theRect.color, // "#884646"
"rootRect.color:", rootRect.color) // "#884646"
blueRect.color = "#123456"
console.log ("color:", color, // "#123456"
"blueRect.color:", blueRect.color, // "#123456"
"theRect.color:", theRect.color, // "#123456"
"rootRect.color:", rootRect.color) // "#123456"
theRect.color = "#ff00ff"
console.log ("color:", color, // "#ff00ff"
"blueRect.color:", blueRect.color, // "#ff00ff"
"theRect.color:", theRect.color, // "#ff00ff"
"rootRect.color:", rootRect.color) // "#ff00ff"
}
}
默认属性——
任何基于Item的类型都有一个data列表属性,这个属性就是该类型的默认属性,保存了所有的孩子对象,其中可视的孩子对象又保存在了children列表属性中,不可视的孩子对象保存在了resources列表属性中,在添加子对象时children、resources属性可写可不写,都会自动添加到对应的属性列表中,所以在之前介绍列表属性的例子中可省略children关键字,修改后如下:
Item {
Text { text: "textOne" }
Text { text: "textTwo" }
Text { text: "textThree" }
Component.onCompleted: {
for(var i = 0; i < children.length; i++)
console.log("text of lable", i, ":", children[i].text)
}
}
另外,我们还可以在自定义属性时添加default关键字,将这个属性作为默认属性。
只读属性——
使用readonly关键字可定义一个只读属性,语法如下:
readonly property <propertyType> <propertyName> : <initialValue>
只读属性必须初始化,且不能修改,也不能是default属性和alias属性,如下所示:
Item {
readonly property int someNumber: 10
Component.onCompleted: someNumber = 20 // TypeError: Cannot assign to read-only property "someNumber"
}
附加属性——
QML语言还包括了一些附加属性和信号处理器,由相应的附加类型提供,使用语法如下:
<AttachingType>.<propertyName>
<AttachingType>.on<SignalName>
在前面的例子中,Component.onCompleted就是一个附加信号处理器,在某些情况下,一个对象的附加属性和信号处理器只对特定的对象有效,如ListView的delegate属性直接授权的对象,而不能在其子对象中直接使用,使用时需要格外注意。