QML 语法基础

QML语法基础描述

QML 是一种多范式语言,它允许根据对象的属性以及它们如何关联和响应其他对象的变化来定义对象。与纯命令式代码相比,在命令式代码中,属性和行为的变化通过一系列逐步处理的语句来表达,而 QML 的声明式语法将属性和行为的变化直接集成到单个对象的定义中。这些属性定义可以包含命令式代码,以应对需要复杂自定义应用行为的情况。

QML源代码通常由引擎通过QML文档加载,这些是QML代码的独立文档。它们可以用来定义QML对象类型,然后在整个应用程序中重复使用。请注意,类型名称必须以大写字母开头,才能在QML文件中声明为QML对象类型。

导入语句

一个QML文档可能在文件的顶部有一个或多个导入。导入可以是以下任意一种:

  • 一个QML模块

  • 一个包含类型定义的相对目录,这些类型定义以QML文档形式存在

  • 一个JavaScript文件

JavaScript 文件在导入时必须进行限定,以便可以访问它们提供的属性和方法。

各种导入的通用形式如下:

  • import [] [as ]

  • import ""

  • import "" [as ]

示例:

  • import QtQuick 2.0

  • import QtQuick.LocalStorage 2.0 as Database

  • import "../privateComponents"

  • import "somefile.js" as Script

请参阅QML语法 - 导入语句文档以获取有关QML导入的深入信息。

对象声明

从语法上讲,一段QML代码定义了要创建的QML对象的树。对象使用对象声明来定义,这些声明描述了要创建的对象的类型以及要赋予对象的属性。每个对象还可以使用嵌套的对象声明来声明子对象。

对象声明由对象类型的名称组成,后跟一组大括号。所有属性和子对象都在这些大括号内声明。

这是一个简单的对象声明:

这声明了一个类型为Rectangle的对象,后面跟着一对大括号,大括号内包含了为该对象定义的属性。Rectangle类型是由QtQuick模块提供的类型,在这种情况下定义的属性是矩形的widthheightcolor属性的值。(这些是由Rectangle类型提供的属性,如Rectangle文档中所述。)

如果上述对象是QML文档的一部分,则可以被引擎加载。也就是说,如果源代码补充了导入QtQuick模块的import语句(以使Rectangle类型可用),如下所示:

当放入.qml文件并由QML引擎加载时,上述代码使用QtQuick模块提供的Rectangle类型创建一个Rectangle对象:

../_images/qtqml-syntax-basics-object-declaration.png

注意

如果一个对象定义只有少量属性,可以像这样写在一行上,属性之间用分号分隔:

显然,这个示例中声明的Rectangle对象确实非常简单,因为它只定义了一些属性值。为了创建更有用的对象,对象声明可以定义许多其他类型的属性:这些内容在QML对象属性文档中有详细讨论。此外,对象声明还可以定义子对象,如下所述。

子对象

任何对象声明都可以通过嵌套对象声明来定义子对象。这样,任何对象声明都隐式声明了一个可能包含任意数量子对象的对象树

例如,下面的Rectangle对象声明包含一个Gradient对象声明,而Gradient对象声明又包含两个GradientStop声明:

当引擎加载此代码时,它会创建一个以Rectangle对象为根的对象树;该对象有一个Gradient子对象,而Gradient子对象又有两个GradientStop子对象。

请注意,这是在QML对象树上下文中的父子关系,而不是在视觉场景中的父子关系。视觉场景中的父子关系概念由QtQuick模块中的Item类型提供,该类型是大多数QML类型的基础类型,因为大多数QML对象旨在进行视觉渲染。例如,Rectangle和Text都是基于Item的类型,下面,一个Text对象被声明为Rectangle对象的视觉子对象:

当上述代码中的Text对象引用其父值时,它引用的是其视觉父级,而不是对象树中的父级。在这种情况下,它们是同一个:Rectangle对象在QML对象树和视觉场景的上下文中都是Text对象的父级。然而,虽然可以修改parent属性来更改视觉父级,但对象树上下文中的对象的父级无法从QML中更改。

(另外,请注意,Text对象已被声明,但没有像前面的示例那样将其分配给Rectangle的属性,前面的示例将Gradient对象分配给矩形的gradient属性。这是因为Item的children属性已被设置为类型的默认属性,以启用这种更方便的语法。)

有关使用Item类型进行视觉父级化概念的更多信息,请参阅视觉父级文档。

评论

在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对象将具有正常的不透明度,因为行opacity: 0.5已被转换为注释。