通过QML文档定义对象类型
QML语言的核心特征之一就是可以很容易在QML文档中以轻量级方式定义QML对象类型,以满足单个QML应用。标准的Qt Quick模块提供了各种类型,像Rectangle、Text和Image,用于构建QML程序;此外,还可以在应用程序中很容易地定义自定义的可重用的QML类型。具有创建自定义类型来构建QML应用程序。
在一个QML文档中定义一个对象类型
命名一个自定义QML对象类型
创建一个对象类型,一个QML文档必须放入一个名称为<TypeName>.qml的文档,其中<TypeName>是类型的名称。类型名字有如下的要求:
- 必须有字符、数字和下划线组成
- 必须以大写字母开头
该文档将被引擎自动识别为定义一个类型的文档。此外,当引擎解析QML类型的名字搜索时,这种方式定义的类型对于同目录下的其他QML文件,自动可见。
自定义QML类型定义
如下例,文档中声明了一个带有一个子对象MouseArea的Rectangle对象。该文档被保存为一个名称为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,那么该文档能被同目录的其他QML文档用作类型SquareButton。例如,同目录下有一个名称为myapplication.qml的文件,该文件可以引用SquareButton类型:
// myapplication.qml
import QtQuick 2.0
SquareButton {}
创建了一个有一个内部鼠标区域的100*100的红色矩形,正如在SquareButton.qml文件中定义的。当myapplication.qml文档被引擎加载时,引擎加载SquareButton.qml文件作为一个组件来实例化创建一个SquareButton对象。
SquareButton类型封装了一个QML对象树。当QML引擎实例化一个SquareButton类型对象时,QML引擎从SquareButton.qml声明的矩形树实例化一个对象。
注,在某些文件系统中字母的大小写是很重要的,像UNIX。建议文件名的大小写与QML类型名完全匹配,比如Box.qml而不是BoX.qml,无论将部署该QML类型的是什么样的平台。
导入定义在当前目录之外的类型
如果SquareButton.qml文件与myapplication.qml文件不在同一目录下,SquareButton类型需要通过在myapplication.qml文件中添加导入声明,使得该类型可见。可以通过文件系统中的相对路径进行导入,或者作为一个已安装模块导入。详见module。
自定义类型属性的访问性
qml文件中定义的跟对象定义了一个QML类型的属性的可访问性。所有的属于该根对象的属性类属性、信号和方法,无论是自定义声明的还是跟对象的QML类型,都能够被外部访问,也能够被该类型的对象读取和修改。
例如,SquareButton.qml文档中定义的根对象类型是Rectangle。意味着任何Rectangle类型定义的任何属性类属性都能被SquareButton对象修改。下面的代码定义了三个SquareButton对象,给出各自自定义的属性类属性的值:
// application.qml
import QtQuick 2.0
Column {
SquareButton { side: 50 }
SquareButton { x: 50; color: "blue" }
SquareButton { radius: 10 }
}
自定类型中可以访问的属性包括所有的自定义属性类属性,具体对象中定义的方法和信号。例如,假设SquareButton.qml定义如下额外的属性类属性、方法和信号:
// SquareButton.qml
import QtQuick 2.0
Rectangle {
id: root
property bool pressed: mouseArea.pressed
signal buttonClicked(real xPos, real yPos)
function randomizeColor() {
root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
property int side: 100
width: side; height: side
color: "red"
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: root.buttonClicked(mouse.x, mouse.y)
}
}
任何SquareButton对象可以使用pressed属性,buttonClicked信号和randomizeColor()方法:
// application.qml
import QtQuick 2.0
SquareButton {
id: squareButton
onButtonClicked: {
console.log("Clicked", xPos, yPos)
randomizeColor()
}
Text { text: squareButton.pressed ? "Down" : "Up" }
}
注意,在SquareButton.qml文件中定义的id值对于SquareButton对象都不可访问,id值只能在组件声明的组件域中可见。上面定义的SquareButton对象无法引用mouseArea为了引用MouseArea子对象,即便该对象的id也取名为root而不是squareButton,这样根对象的id值相同也不会引起冲突,因为两个对象声明在不同的域当中。