Introduction to the QML language

QML是一种声明式语言,设计用来描述一个程序的UI是什么样、行为如何的。在QML中,一个拥有属性的对象树可以指定一个UI。

这个介绍是针对那些只有很少或者没有编程经验的人员的。在QML中,使用JavaScript作为脚本语言,因此你可能要在深入QML之前多学习一下它。对诸如HTML和CSS的其他网络技术有一定的了解也能有所帮助,但并非必须的。

Basic QML Syntax

QML看起来这样:

0
Rectangle {
    width: 200
    height: 200
    color: "blue"

    Image {
        source: "pics/logo.png"
        anchors.centerIn: parent
    }
}

这里我们创建了两个对象,一个Rectangle和它的孩子Image。对象由它们的类型指定,后跟一对花括号,其中可以定义这个对象的其他数据,像属性值和其他孩子。

语法property: value可以指定属性。在上面的例子里,我们可以看到对象Image有一个名叫source的属性,我们给它指定了“pics/logo.png”这个值。属性和值之间用分号分隔开。

属性可以一行一行的指定:

Rectange {
    width: 100
    height: 100
}

或者你可以将多个属性放在一行:

height: 100 }


当多个属性/值对在同一行里指定,它们之间必须用分号分隔开来。

import声明引入了QtQuick模块,这个模块中包含所有标准的QML元素。没有这行import,Rectangle和Image元素都是不可用的。

Comments

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
}


上面的例子中,由于opacity: 0.5这行被注释掉,对象Text是标准的不透明度。

Object identifiers

每个对象都可以给定一个特殊的id值,用来识别该对象以及被其他对象引用到。

举例而言,下面的例子中我们有两个Text对象。第一个的id是“text1”。第二个Text只需要引用text1.text,就可以将自己的text属性的值设定成与第一个对象相同:

0

 Row {
     Text {
         id: text1
         text: "Hello World"
     }

     Text { text: text1.text }
 }

在对象被声明的组件里,一个对象在任何地方都可以通过它的id引用到。因此,在一个组件中,id值必须一直是独一无二的。

对一个QML对象而言,id的值是特殊的,不应被视作一个普通的对象属性;例如:在上面的例子中,text1.id是不能访问的。一旦一个对象被创建了,它的id是不能更改的。

注意,id值必须使用小写字母或者下划线作为开始,并且不能包含字母、数字和下划线意外的字符。

Expressions

可以使用JavaScript表达式来指定属性值。例如:

Item {
     width: 100 * 3
     height: 50 + 22
 }

加入建立了属性绑定(Property Binding),这些表达式可以包括其他对象和属性的引用。当表达式改变了,表达式对应的属性的值也会自动更新为新的值。

Item {
     width: 300
     height: 300

     Rectangle {
         width: parent.width - 50
         height: 100
         color: "yellow"
     }
 }

这里,Rectangle对象的width属性与它的父亲的width有关。任何时候它父亲的width改变了,Rectangle的也将自动更新。

Properties

Basic property types

QML支持多种类型的属性。基本的类型包括int,real,bool,string和color。

Item {
     x: 10.5             // a 'real' property
     state: "details"    // a 'string' property
     focus: true         // a 'bool' property
     ...
 }

QML属性是类型安全的。换言之,你只能给它们指定一个与其属性的类型匹配的值。例如,x的属性是一个real,如果你给它指定一个string就会出错。

Item {
     x: "hello"  // illegal!
 }

注意,限于Attached Properties异常,属性只能有小写字母开头。

Property change notifications

当属性的值发生变化,它会发出一个signal通知其他属性。

很简单,创建一个名为on<属性>Changed的signal handler就可以接收到这些信号。例如,Rectangle元素包含width和color属性。下面我们有另一个Retangle对象,它定义了onWidtChanged和onColorChanged的两个signal handler,当这些属性被修改时候,它们就会被自动调用。

Rectangle {
     width: 100; height: 100

     onWidthChanged: console.log("Width has changed to:", width)
     onColorChanged: console.log("Color has changed to:", color)
 }

signal handler在下面做了进一步解释。

List properties

列表的属性看起来是这样的:

Item {
    children: [
        Image {},
        Text {}
    ]
}

列表被方括号括起来,用逗号分割开来。如果你只是给列表指定一项,可以忽略掉方括号。

Image {
     children: Rectangle {}
 }

可以使用索引值访问列表中的项。查看list type文档来获取关于属性和可用操作的更多信息。

Default properties

每个对象类型可以指定列表中的一个或者对象的属性作为它的缺省属性。如果一个属性已经被声明了,property标签可以忽略掉。

例如下面的代码:

State {
     changes: [
         PropertyChanges {},
         PropertyChanges {}
     ]
 }


可以简写为:

State {
     PropertyChanges {}
     PropertyChanges {}
 }

就是因为changes是State类型的缺省属性。
Grouped Properties

很多情况下,有逻辑分组的属性可以使用.或者分组符号来显示:

Text {
     font.pixelSize: 12
     font.bold: true
 }

或者像这样:

Text {
     font { pixelSize: 12; bold: true }
 }

在元素分档里,使用.来显示分组属性。

Attached Properties

很多对象附加属性到其他另一个对象。附加属性表示为Type.property的形式,其中Type是附加属性的元素的类型。

例如ListView元素附加了ListView.isCurrentItem属性到它创建的每一个代理上。

Component {
     id: myDelegate
     Text {
         text: "Hello"
         color: ListView.isCurrentItem ? "red" : "blue"
     }
 }
 ListView {
     delegate: myDelegate
 }

另外一个附加属性的例子是Keys元素,它附加了对任何一个Item进行按键处理需要的属性。

Item {
     focus: true
     Keys.onSelectPressed: console.log("Selected")
 }

Signal Handlers

signal handler允许执行JavaScript代码来响应一个事件。例如,MouseArea元素有一个onClicked的handler,可以用来响应鼠标点击。下面,只要鼠标被点击了,我们使用这个handler就可以打印出一个消息:

Item {
     width: 100; height: 100

     MouseArea {
         anchors.fill: parent
         onClicked: {
             console.log("mouse button clicked")
         }
     }
 }

所有的signal handler为“on”开始。

很多signal handler包含可选参数。例如,MouseArea的onPressed有一个mouse参数,其中包含了鼠标按下的信息。可以在JavaScript代码中引用这个参数,像下面这样:

MouseArea {
     acceptedButtons: Qt.LeftButton | Qt.RightButton
     onPressed: {
         if (mouse.button == Qt.RightButton)
             console.log("Right mouse button pressed")
     }
 }

相关文章: