QML Syntax Basics
QML是一种多范式语言, 它允许对象定义它们的属性, 及如何与其他对象关联和响应改变. 与纯命令式代码不同, QML的声明性语法将属性和行为的变化直接集成到单个对象的定义中, 其中属性和行为的变化通过一系列逐步处理的语句来表达. 在需要复杂的自定义应用程序行为的情况时, 属性定义可以包括命令式代码.
QML源代码通常由引擎通过QML文档加载, QML文档是QML代码的独立文档. 这些可以用于定义 QML对象类型, 然后在整个应用程序中重用这些对象类型.
注意: 类型名称必须以大写字母开头, 才能在QML文件中声明为QML对象类型.
导入声明
QML文档可能在文件的顶部包含一个或多个导入. 导入可以是下列之一:
- 类型已注册到版本化的命名空间 (如., 通过插件)
- 包含作为QML文档的类型定义的相对目录
- JavaScript文件
JavaScript文件导入必须保证正确, 以便可以访问它们提供的属性和方法.
各类导入方式如下:
import Namespace VersionMajor.VersionMinor
import Namespace VersionMajor.VersionMinor as SingletonTypeIdentifier
import "directory"
import "file.js" as ScriptIdentifier
示例:
import QtQuick 2.0
import QtQuick.LocalStorage 2.0 as Database
import "../privateComponents"
import "somefile.js" as Script
有关QML导入详见e QML Syntax - Import Statements.
对象声明
语法上, QML代码块定义一个要创建的QML对象树. 对象由 对象声明 定义, 对象声明描述要创建的对象的类型及属性. 每个对象也可以使用嵌套对象声明子对象.
对象声明由对象类型的名称和一组大括号组成, 然后在这些大括号中声明所有属性和子对象.
下面是一个简单的对象声明:
Rectangle { width: 100 height: 100 color: "red" }
上述代码声明一个 Rectangle对象, 紧跟一组大括号, 包含对象定义的属性. Rectangle 类型是由 QtQuick
模块提供, 这里定义 width
, height
和 color
的值. (这些属性由 Rectangle 提供, 详见 Rectangle.)
上述代码作为 QML 文档的一部分. 由QML引擎加载. 也就是说, 如果源代码由 import 语法导入 QtQuick
模块 (使 Rectangle 类型可用), 如下所示:
import QtQuick 2.0 Rectangle { width: 100 height: 100 color: "red" }
QML引擎加载 .qml
文件后, 上述代码使用QtQuick
模块的 Rectangle 对象:
注意: 如果一个对象只定义少数属性, 那么它可以写在一行, 属性间用";"分隔:
Rectangle { width: 100; height: 100; color: "red" }
显然, 本例中声明的 Rectangle 对象非常简单, 它仅定义几个属性值. 一个对象可以定义许多其他类型的属性, 参见 QML Object Attributes. 此外, 对象声明可以定义子对象, 如下所示.
子对象
任何对象都可以通过嵌套的方式声明子对象. 也就是说, 任何对象声明都隐式声明一个对象树, 对象树可以包含任意数量的子对象.
例如, 下面声明的 Rectangle 对象包含一个 Gradient 对象声明, Gradient对象又包含两个 GradientStop 声明:
import QtQuick 2.0 Rectangle { width: 100 height: 100 gradient: Gradient { GradientStop { position: 0.0; color: "yellow" } GradientStop { position: 1.0; color: "green" } } }
引擎加载上述代码时, 它会创建一个对象树, 根部有一个 Rectangle 对象; Rectangle对象有一个 Gradient 子对象, Gradient子对象又有两个 GradientStop 子对象.
注意: QML对象树是父子关系. 父子关系由QtQuick
模块的 Item 类型提供, 这个类型是大多数QML类型的基本类型, 因为它们旨在视觉渲染. 例如, Rectangle 和 Text 都是 Item类型, 下述代码, Text 对象是 Rectangle 对象的子对象:
import QtQuick 2.0 Rectangle { width: 200 height: 200 color: "red" Text { anchors.centerIn: parent text: "Hello, QML!" } }
上述代码中, Text 对象引用父对象的值时, 它指可视父级, 而不是对象树中的父级. 在这种情况下, 它们是相同的: Rectangle 对象是QML对象树和视觉场景中Text对象的父对象. 但是, 虽然可以修改视觉场景的父级, 但是无法修改对象树的父级.
(注意: 此外, Text 对象是在在没有将其分配给 Rectangle属性的情况下声明的, 这与之前的示例不同, 前者将 Gradient 对象分配给rectangle的 gradient
属性. 这是因为Item的 children 属性已设置为类型的默认属性, 以启用此更方便的语法.)
有关Item类型的可视化父子关系概念, 详见 visual parent.
注释
QML的注释语法与JavaScript的语法类似:
- 单行注释: //开始, 行尾结束.
- 多行注释: /*开始, */结束
Text { text: "Hello world!" //a basic greeting /* We want this text to stand out from the rest so we give it a large size and different font. */ font.family: "Helvetica" font.pointSize: 24 }
处理QML代码时, 引擎会忽略注释. 它们对于解释代码的一部分正在做什么很有用, 无论是供以后参考还是向其他人解释实现.
注释也可以用来阻止代码的执行, 这有时对跟踪问题很有用.
Text { text: "Hello world!" //opacity: 0.5 }
在上述示例中, Text 对象将具有正常的不透明度, 因为线不透明度: 0.5已变为注释.