通过QML文档定义对象类型#
QML文档作为可重用类型定义的描述
QML的一个核心特性是通过QML文档以轻量级方式定义QML对象类型,以适应单个QML应用程序的需求。标准的Qt Quick模块提供各种类型,如矩形、文本和图像,用于构建QML应用程序;除此之外,你可以轻松地定义自己的QML类型以便在应用程序中重用。创建自己的类型的能力是任何QML应用程序的基础。
使用QML文件定义对象类型#
自定义QML对象类型的命名#
要创建一个对象类型,应将一个QML文档放入一个名为<TypeName>.qml的文本文件中,其中<TypeName>是类型期望的名称。类型名称有以下要求
它必须由字母数字字符或下划线组成。
它必须以大写字母开头。
然后此文档将自动由引擎识别为QML类型的定义。此外,以这种方式定义的类型将自动对同一本地目录中的其他QML文件提供,因为引擎在解析QML类型名称时_search_立即目录。
注意
QML引擎不自动以这种方式搜索远程目录。如果你的文档通过网络加载,你必须添加一个qmldir文件。参见导入QML文档目录。
自定义QML类型定义#
例如,下面是一个声明一个带有子MouseArea的矩形的文档。文档已保存到名为SquareButton.qml
的文件中
由于文件名为SquareButton.qml
,因此任何同一目录中的其他QML文件都可以作为类型名称使用SquareButton
。例如,如果同一目录中有一个myapplication.qml
文件,它可以引用SquareButton
类型
这创建了一个100 x 100的红色矩形,内部有一个MouseArea,正如在SquareButton.qml
中定义的那样。当此myapplication.qml
文档由引擎加载时,它加载SquareButton.qml文档作为组件并将其实例化以创建一个SquareButton
对象。
SquareButton
类型封装了在SquareButton.qml
中声明的QML对象树。当QML引擎从这个类型中实例化一个SquareButton
对象时,它是从SquareButton.qml
中声明的矩形对象树实例化一个对象。
注意
在有些文件系统(尤其是UNIX文件系统)中,文件名的大小写很重要。建议文件名的大小写与所需的QML类型名称完全匹配 - 例如,Box.qml
而不是 BoX.qml
- 不论QML类型部署的平台如何。
内联组件#
有时,为类型创建新文件可能不方便,例如在多个视图中重用小的代理。如果您不需要公开类型,只需创建一个实例,可以使用 Component。但如果您想声明组件类型的属性,或者您想在多个文件中使用它,则 Component
不是一种选择。在这种情况下,您可以使用内联组件。内联组件在文件内部声明了一个新组件。该语法如下
component <component name> : BaseType { // declare properties and bindings here }
在内联组件声明的文件内部,可以通过其名称简单引用类型。
// Images.qml import QtQuick 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 Rectangle { property alias caption: image.caption property alias source: image.source border.width: 2 border.color: "black" Images.LabeledImage { id: image } }
注意
内联组件不与声明它们的组件共享作用域。在以下示例中,当文件 B.qml 中的 A.MyInlineComponent
被创建时,将会发生 ReferenceError,因为在 B.qml 中作为 id 的根不存在。因此,建议不要在内联组件中引用不属于它的对象。
// A.qml
import QtQuick
Item {
id: root
property string message: "From A"
component MyInlineComponent : Item {
Component.onCompleted: console.log(root.message)
}
}
// B.qml
import QtQuick
Item {
A.MyInlineComponent {}
}
注意
内联组件不能嵌套。
导入当前目录之外定义的类型#
如果 SquareButton.qml
不在 myapplication.qml
的同一目录中,则 SquareButton
类型需要通过 myapplication.qml
中的 import 语句特别提供。它可以从一个文件系统上的相对路径导入,也可以作为一个已安装的模块导入;请参阅 模块 获取更多详细信息。
自定义类型的访问属性#
在 .qml 文件中的 root 对象 定义 定义了 QML 类型可用的属性。属于此根对象的全部属性、信号和方法(无论是自定义声明还是来自根对象的 QML 类型)都是外部可访问的,并且可以对此类型的对象进行读取和修改。
例如,上面 SquareButton.qml
文件中的根对象类型是 Rectangle。这意味着可以修改 SquareButton
类型根 Rectangle 对象的定义的任何属性。下面的代码定义了三个具有根 Rectangle 对象属性定制值的 SquareButton
对象
可访问的自定义 QML 类型对象的属性包括任何 自定义属性、方法 和 信号。例如,假设 SquareButton.qml
中的 Rectangle 定义如下,增加了属性、方法和信号
任何 SquareButton
对象都可以使用添加到根矩形中的 pressed
属性、buttonClicked
信号和 randomizeColor()
方法。
请注意,任何在 SquareButton.qml
中定义的 id
值都不可访问于 SquareButton
对象,因为 id 值只能在组件声明的组件作用域中访问。上面定义的 SquareButton
对象不能通过 mouseArea
来引用鼠标区域的子项,并且如果它有一个 id
为 root
而不是 squareButton
,则不会与在 SquareButton.qml
中定义的根对象同一值冲突,因为这两个都会在单独的作用域内声明。