QML 是一种描述用户界面的声明式语言。它将用户界面分解成一些更小的元素,这些元素能够结合成一个组件。QML 语言描述了用户界面元素的形状和行为。用户界面能够使用 JavaScript 来提供修饰,或者增加更加复杂的逻辑。从这个角度来看它遵循 HTML-JavaScript 模式,但 QML 是被设计用来描述用户界面的,而不是文本文档。
从 QML 元素的层次结构来理解是最简单的学习方式。子元素从父元素上继承了坐标系统,它的 x,y 坐标总是相对应于它的父元素坐标系统。
一、入门示例
让我们开始用一个简单的 QML 文件例子来解释这个语法。
// rectangle.qml
import QtQuick 2.0
// 根元素
Rectangle {
// 将此根元素命名为root
id: root
// 属性 - properties: <name>: <value>
width: 120
height: 240
// color property(颜色属性)
color: "#D8D8D8"
// 声明一个嵌套元素(root的子元素)
Image {
id: rocket
// 相对parent的x坐标
x: (parent.width - width)/2; y: 40
source: 'assets/rocket.png'
// root的另一个子元素:文本元素
Text {
// 根据id对应元素的属性,设置y坐标
y: rocket.y + rocket.height + 20
width: root.width
horizontalAlignment: Text.AlignHCenter
text: 'Rocket'
import 声明导入了一个指定的模块版本。类似于 C++ 中的 include,在 QML 中使用 import 语句导入模块,模块中包含了各种 QML 类型。
使用 // 可以单行注释,使用 /**/ 可以多行注释,就像 C/C++ 和 JavaScript 一样。
每一个 QML 文件都需要一个根元素,就像 HTML 一样。
一个元素使用它的类型声明,然后使用 {} 进行包含。
元素拥有属性,他们按照 name:value 的格式来赋值。
任何在 QML 文档中的元素都可以使用它们的 id 进行访问(id 是一个任意的标识符)。
元素可以嵌套,这意味着一个父元素可以拥有多个子元素。子元素可以通过访问 parent 关键字来访问它们的父元素。
你会经常使用 id 或者关键字 parent 来访问你的父对象。有一个比较好的方法是命名你的根元素对象 id 为 root,这样就不用去思考你的 QML 文档中的根元素应该用什么方式命名了。
二、QML类型
QML 的类型系统包含了基本类型、 QML 对象类型和 JavaScript 类型,这些类型组成了整个 QML 文档。 所有 QML 类型表请参考:qml类型有那些?
2.1 基本类型
在 QML 中将指向简单数据的类型称为基本类型,比如 int 或 string 等。更多请查阅官方文档:QML Basic Types
QML 引擎默认支持某些基本类型,不需要使用 import 语句,而其他一些则需要客户端导入提供它们的模块。下面列出的所有基本类型都可以用作 QML 文档中的 property 类型,但以下情况除外:
list 必须与 QML 对象类型结合使用
enumeration 不能直接使用,因为枚举必须由已注册的QML对象类型定义
QML语言提供的基本类型
下列是 QML 语言本身提供的基本类型:
2.2 QML 对象类型
QML 对象类型就是可以实例化 QML 对象的类型。
从语法术语来说,QML 对象类型是一种可以用来声明对象的方法,方法是指定类型名称,后跟一组包含该对象属性的花括号。例如,代码中 Window 和 Text 都是对象类型。当对象类型被实例化以后,就被叫做该对象类型的对象,例如 Text 对象类型在代码中被实例化为了 Text 类型的对象 Text,之所以这两个概念容易被混淆,是因为它们是同名的。只需要记住对象类型后面添加 {} 后就被称为对象
,大家也可以类比 C++ 中的类与实例化。 更多请查阅官方文档:QML Object Types
(1)通过 QML 文档定义对象类型
插件编写者和应用程序开发人员可以提供定义为 QML 文档的类型。当 QML 文档对 QML 导入系统可见时,它定义一种类型,该类型由文件名减去文件扩展名标识。
因此,如果存在一个名为 “MyButton.qml” 的 QML 文档,它将提供名为 MyButton 的对象类型定义,该对象类型可在 QML 应用程序中直接使用。
(2)用 Component 内联定义类型
在QML中创建对象类型的另一种方法是使用 Component 类型。这允许在QML文档中内联定义类型,而不是在文件中使用单独的文档 .qml。
Item {
id: root
width: 500; height: 500
Component {
id: myComponent
Rectangle { width: 100; height: 100; color: "red" }
Component.onCompleted: {
myComponent.createObject(root)
myComponent.createObject(root, {"x": 200})
在这里,myComponent 对象本质上定义了一个匿名类型,可以使用 Component :: createObject 实例化该匿名类型以创建此匿名类型的对象。
请注意,每个 Component 对象声明都会创建自己的组件范围。在 Component 对象声明中使用和引用的任何 id 值在该范围内必须是唯一的,但在声明内联组件的文档中不必唯一。有关更多详细信息,请参见:作用域和命名分辨率。
(3)从C ++定义对象类型
C++ 插件编写者和应用程序开发人员可以通过 Qt QML 模块提供的API注册用 C++ 定义的类型。有多种注册功能,每种注册功能都可以满足不同的用例。有关这些注册功能的详细信息,以及将自定义 C++ 类型公开给 QML 的详细信息,请参阅有关 Defining QML Types from C++ 的文档。
QML 类型系统依赖于安装在已知导入路径中的导入,插件和扩展。插件可以由第三方开发人员提供,并由客户端应用程序开发人员重复使用。请参阅有关 QML modules 的文档,以获取有关如何创建和部署QML扩展模块的更多信息。
2.3 JavaScript 类型
QML 支持 JavaScript 对象和数组,可以通过 var 类型创建并存储任何标准的 JavaScript 类型。var 可以支持的类型: