qml 是一种多范式语言,使对象能够根据其属性以及如何关联和响应其他对象的更改来定义对象。与纯粹的命令式代码相反,属性和行为的变化通过一系列逐步处理的语句表达。qml 的声明性语法将属性和行为更改直接集成到单个对象的定义中,这些属性定义可以包含必要的代码,在情况复杂的自定义应用程序行为是必要的。
qml 源代码通常由引擎通过 qml 文档加载,qml 文档是 qml 代码的独立文档。这些可以用于定义 qml 对象类型,然后可以在整个应用程序中重复使用。
<a href="#%e7%ae%80%e8%bf%b0">简述</a>
<a href="#%e5%af%bc%e5%85%a5%e8%af%ad%e5%8f%a5">导入语句</a>
<a href="#%e5%af%b9%e8%b1%a1%e5%a3%b0%e6%98%8e">对象声明</a>
<a href="#%e5%ad%90%e5%af%b9%e8%b1%a1">子对象</a>
<a href="#%e6%b3%a8%e9%87%8a">注释</a>
qml 文档可以在文件的顶部包含一个或多个 import 语句。一个 import 可以是以下任何一种:
一个已经注册了类型的版本化命名空间(例如:通过插件)
一个包含 qml 文档类型定义的相对目录
一个 javascript 文件
在导入时,javascript 文件的导入必须是合格的,以便可以访问其提供的属性和方法。
各种 import 的通用形式如下:
<code>import namespace versionmajor.versionminor</code>
<code>import namespace versionmajor.versionminor as singletontypeidentifier</code>
<code>import "directory"</code>
<code>import "file.js" as scriptidentifier</code>
例如:
<code>import qtquick 2.0</code>
<code>import qtquick.localstorage 2.0 as database</code>
<code>import "../privatecomponents"</code>
<code>import "somefile.js" as script</code>
在语法上,一个 qml 代码块定义了一个要被创建的 qml 对象树。使用对象声明来定义对象,对象声明描述了要创建对象的类型以及要给予对象的属性。每个对象也可以使用嵌套对象声明来声明子对象。
一个对象声明包含:
对象类型的名称(例如:rectangle )
一组花括号<code>{ }</code>: 紧随其(对象类型的名称)后
属性(例如:width)和子对象(例如:text):在花括号中声明
来看一个简单的对象声明:
这声明了一个类型为 rectangle 的对象(rectangle 类型由 qtquick 模块提供),后跟一组包含为该对象定义属性的花括号,定义的属性是矩形的 width (宽度)、height(高度)和 color(颜色)。
如果上述对象是 qml 文档的一部分,则可以由引擎加载。也就是说,如果源代码用导入 qtquick 模块的 import 语句来补充(使 rectangle 类型可用),如下所示:
当放置到 .qml 文件中并由 qml 引擎加载时,上述代码会使用 qtquick 模块提供的 rectangle 类型创建一个 rectangle 对象:
注意:如果对象定义只有少量的属性,可以写在单行,用分号分隔:
显然,这个例子中声明的 rectangle 对象很简单,因为只定义了几个属性值。为了创建更多有用的对象,对象声明可以定义许多其他类型的属性(在下一节中讨论)。另外,对象声明还可以定义子对象,如下所述。
任何对象声明都可以通过嵌套的对象声明来定义子对象。通过这种方式,任何对象声明隐式声明了一个对象树,可以包含任意数量的子对象。
例如,下面的 rectangle 对象声明包含了一个 gradient 对象声明,gradient 又包含了两个 gradientstop 声明:
当代码被引擎加载时,会创建一个对象树,在根处有一个 rectangle 对象;这个对象有一个 gradient 子对象,gradient 又有两个 gradientstop 子对象。
然而,这是一个在 qml 对象树的上下文中的父子关系,而不是在视觉场景的上下文中。在视觉场景中的父子关系的概念由来自 qtquick 模块的 item 类型提供,qtquick 模块是大多数 qml 类型的基本类型,因为大多数 qml 对象旨在可视化地呈现。
例如,rectangle 和 text 都是基于 item 的类型,而在下面,一个 text 对象已经被声明为一个 rectangle 对象的可视化子对象:
在上述代码中,当 text 对象引用它的 parent 值时,指的是它的视觉 parent,而不是对象树中的 parent。在这种情况下,它们是一样的:rectangle 对象既是 qml 对象树,又是视觉场景的上下文中的 text 对象的 parent。然而,尽管可以修改 parent 属性以更改视觉父对象,但是对象树的上下文中的一个对象的父对象不能从 qml 更改。
(另外,请注意,text 对象已经被声明了,而没有赋值给 rectangle 的属性,这与将 gradient 对象赋值给 rectangle 的 gradient 属性的前面的例子不同,这是因为 item 的 children 属性已经被设置为类型的默认属性来启用这个更方便的语法。)
在 qml 中,注释的语法与 javascript 类似:
单行注释:以 <code>//</code> 开头,并在行尾结束。
多行注释:以 <code>/*</code> 开头,以 <code>*/</code> 结尾。
引擎在处理 qml 代码时会忽略注释。注释的好处很多:
有助于解释代码以提高其可读性,便于日后自己参考或者他人阅读。
用于防止代码执行,这有时对跟踪问题非常有用。
这时,text 对象将具有正常的透明度,因为行 <code>opacity: 0.5</code> 已经被注释掉了。
项目验收时,序猿演示功能,猛戳按钮愣是没反应。。。闷头走向工位,打开源码,发现了神奇的 <code>// todo</code>