通过 QML 文档定义对象类型
QML 的核心特性之一是它可以通过 QML 文档轻量级地定义 QML 对象类型,以满足单个 QML 应用程序的需求。标准的 Qt Quick 模块提供了如 Rectangle、Text 和 Image 等多种类型,用于构建 QML 应用程序;除此之外,你可以轻松地定义自己的 QML 类型以便在应用程序中复用。创建自定义类型的这种能力是任何 QML 应用程序的基础。
使用 QML 文件定义对象类型
自定义 QML 对象类型的命名
要创建一个对象类型,应该将 QML 文档放入一个命名为 <TypeName>.qml 的文本文件中,其中 <TypeName> 是所需的类型名称。类型名称有以下要求:
- 必须由字母数字字符或下划线组成。
- 必须以大写字母开头。
此文档随后将被引擎自动识别为 QML 类型的定义。此外,这种方式的定义将自动提供给同一本地目录中的其他 QML 文件,因为引擎在解析 QML 类型名称时会在直接目录中搜索。
注意:QML 引擎不会以这种方式自动搜索远程目录。如果你的文档通过网络加载,你必须添加 qmldir 文件。请参见 导入 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 x 100 的红色 Rectangle,内部有一个 MouseArea,正如在 SquareButton.qml
中定义的那样。当引擎加载此 myapplication.qml
文档时,它将加载 SquareButton.qml 文档作为组件,并将其实例化以创建一个 SquareButton
对象。
SquareButton
类型封装了 SquareButton.qml
中声明的 QML 对象树。当 QML 引擎从该类型实例化 SquareButton
对象时,它将实例化来自 SquareButton.qml
中声明的 Rectangle 树的对象。
注意:在某些文件系统中(特别是UNIX),文件名的字母大小写很重要。建议文件名的大小写与所需的QML类型名称完全匹配——例如,Box.qml
而不是BoX.qml
——无论将QML类型部署到哪个平台。
内联组件
有时,为类型创建新文件可能不方便,例如在多个视图中重复使用一个小型代理时。如果您不需要公开类型,而只需创建一个实例,可以使用<(bit translate="no">Component),但是如果您想声明组件类型属性,或者想在多个文件中使用它,则不可使用Component
。在这种情况下,您可以使用<生活中的组件Maker。内联组件在文件内部声明了新的组件。其语法如下
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为root
的对象。因此,建议不要在内联组件中引用不属于它的对象。
// 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
所在的目录中,则需要通过在myapplication.qml
中特别提供的SquareButton
类型公开。它可以从文件系统上的相对路径导入,或作为已安装的模块导入;有关更多详细信息,请参阅模块。
自定义类型的可访问属性
.qml文件中的
例如,上述SquareButton.qml
文件中的root对象类型是Rectangle。这意味着可以修改属于Rectangle类型的任何属性,并定义以下三个带有自定义值的SquareButton
对象
// application.qml import QtQuick 2.0 Column { SquareButton { side: 50 } SquareButton { x: 50; color: "blue" } SquareButton { radius: 10 } }
自定义QML类型的对象可访问的属性包括任何已定义的自定义属性、方法和信号。例如,假设Rectangle在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: (mouse)=> root.buttonClicked(mouse.x, mouse.y) } }
任何SquareButton
对象都可以使用添加到rootRectangle的pressed
属性、buttonClicked
信号和randomizeColor()
方法。
// application.qml import QtQuick 2.0 SquareButton { id: squareButton onButtonClicked: (xPos, yPos)=> { console.log("Clicked", xPos, yPos) randomizeColor() } Text { text: squareButton.pressed ? "Down" : "Up" } }
请注意,在 SquareButton.qml
中定义的任何 id
值都无法访问到 SquareButton
对象,因为 id 值只能在组件声明的组件范围内访问。上述 SquareButton
对象定义不能引用 mouseArea
以引用其 MouseArea 子项,并且如果它有一个而非 squareButton
的 id
为 root
,则不会与在 SquareButton.qml
中定义的根对象的相同值 id
冲突,因为这两个是在不同的作用域中声明的。
© 2024 Qt公司。此处包含的文档贡献是各自所有者的版权。提供的文档受GNU自由文档许可证版本1.3的条款约束,由自由软件基金会发布。Qt及其相关标志是芬兰以及/或其他国家Qt公司的商标。所有其他商标均为各自所有者的财产。