原文地址
本文地址 http://blog.chinaunix.net/uid-374124-id-4661152.html
本文由高频DNA翻译整理,转载请注明出处。本贴将不定时更新扩充内容,请点击原贴地址获得最新文章。
QML文档与QML语法
QML文档组成元素有:导入、对象树和注释
QML文档结构包括两个部分:导入和对象树
例子:
/*这是一个QML文档的例子*/
import QtQuick 2.0 //导入
Rectangle { //根对象声明,对象树的根
width: 100 //属性绑定
height: 100
Text { 子对象声明
text: "hellow world!"
}
}
一个QML文档可以由QML引擎从“.qml”文件中加载,也可以使用代码构建。
QML文档是独立的QML源代码,一个文档定义了一个新的QML对象类型。定义与重用对象类型是QML语言的核心能力之一。
QML文档的导入部分
导入指示了文档能够使用的QML对象类型的模块和JavaScript资源。默认情况下,文档能够访问到与其同目录下的其他qml文件定义的对象类型。如果要引用其他QML对象类型的话,就要导入该类型所在的名字空间。
导入由一条或多条位于文档顶部的导入语句构成,QML文档可以导入以下几种类型的组件:
? QML对象类型的注册名字空间以其版本号(即该对象类型所在模块)
? QML文件所在的目录
? JavaScript文件
例子:
import QtQuick 2.0
import QtQuick.LocalStorage 2.0 as Database
import "../privateComponents"
import "somefile.js" as Script
更多关于import的深入内容请参考 QML Syntax - Import Statements
文档中的对象声明部分
语法上,文档的对象声明代码块描述了一个对象层次结构——QML对象树。对象声明包含对象的类型以及相关特性,以及嵌套声明的其他对象,构建对象树父子关系。孩子对象自动地添加到父对象的children属性里,每个文档仅能有一个根对象声明。
对象声明:类型名字后跟着一组大括号。对象所有的特性和孩子对象都要声明在大括号里。
Rectangle {
width: 100
height: 100
color: "red"
}
如果对象定义只有少量属性,可以写成一行,属性用分号间隔:
Rectangle { width: 100; height: 100; color: "red" }
任何对象声明都能够声明一颗包含大量孩子对象的对象树结构。
例子:
Rectangle {
width: 100
height: 100
gradient: Gradient {
GradientStop { position: 0.0; color: "yellow" }
GradientStop { position: 1.0; color: "green" }
}
}
Rectangle是根对象,它有一个孩子Gradient,Gradient又有两个孩子GradientStop。
但它们只是对象树结构中的父子关系,并不表示视图中的父子关系。视图中的父子关系是由QtQuick模块的Item类型提供,它是QML中大多数类型的基类型,因为大多数的QML类型都是可渲染的。例如,rectangle和text在基类都是item,以下声明中,text对象就是rectangle在视图中孩子对象。
import QtQuick 2.0
Rectangle {
width: 200
height: 200
color: "red"
Text {
anchors.centerIn: parent
text: "Hello, QML!"
}
}
在代码中,对象的parent值指的是它的视图父亲,而不是对象树中的父亲。上面的例子中rectangle既是text的视图父亲也是它在对象树中的父亲。但是对象的视图父亲是可以改变的,对象树父亲是不能更改的。
与之前的代码不,text并没有显示地赋给rectangle的某个属性,而被赋给了继承自item类型的默认属性children属性。
更多关于视图父亲的深入内容请参考visual parent
文档中的注释
QML文档中的注释与C语言注释相同
//表示行注释
/*…*/表示块注释
QML组件
组件是QML对象类型的定义。组件可以创建它的实例,即QML对象。
组件定义的两种方式:文档组件和内联组件
文档组件:
文档组件通过.qml文件来定义组件。一个QML文档保存为一个独立的.qml文件。
内联组件:
在文档内部,通过组件类型Component内联地定义组件。
组件类型Component的例子:
import QtQuick 2.0
Item {
width: 100; height: 100
Component {
id: redSquare //组件ID
Rectangle { //组件根元素
color: "red"
width: 10
height: 10
}
}
Loader { sourceComponent: redSquare } //组件经过加载后才能使用
Loader { sourceComponent: redSquare; x: 20 }
}
注意通常Rectangle类型能够自动地渲染并显示,但例子中的Rectangle类型并不如此,因为它被定义在一个组件类型Components中。这种类型会把它里面的QML对象声明进行封装,就像是在定义一个独立的qml文件一样,但是只有在请求的情况下才会加载这个组件(例子中使用了两个Loader对象进行加载)。
组件封装一个QML类型,使其可重用且具有良好定义的接口。
文档组件与内联组件相似,它们都有一个根元素,组件所有的行为和特性都必须声明在这个根元素里。内联组件有组件ID,例子中组件ID在根元素Rectangle之外声明。
内联组件文档组件中通常作为可重用的小组件,并且只能在声明它的文件中使用。
内联组件通常用在视图中作为图形组件来使用。
QML对象特性
每一个QML对象类型都有一组预先定义好的特性。每一个QML对象实例都是使用其类型相关的特性来创建。QML文档中的对象树定义一个新的QML对象类型。创建这个对象类型的实例,也就是在实例化一个对象树的层次结构。QML对象类型的特性有如下几种:
? the id attribute ID特性
? property attributes 属性特性
? signal attributes 信号特性
? signal handler attributes 信号处理器特性
? method attributes 方法特性
? attached properties and attached signal handler attributes 附加属性特性及附加信号处理器特性
ID特性
每种QML对象类型都有一个ID特性。这个特性由QML语言提供,无法重定义或被其他QML对象类型覆盖。给一个对象实例的ID赋值,其他对象就可以识别和引用该对象。对象的ID必须以小写字母或下划线开头,并且不能包含非字母,数字或下划线的字符。
在对象被声明的组件范围内,对象的ID必须是唯一的,在任何地方都可以通过ID来引用这个对象。
当对象实例被创建后,虽然ID看起来像是一个普通的属性特性,但它却不是一般的属性特性,用法上有自己特殊的句法。如myTextInput表示一个对象,myTextInput.text 合法,但myTextInput.id是不合法的。
import QtQuick 2.0
Column {
width: 200; height: 200
TextInput { id: myTextInput; text: "Hello World" }
Text { text: myTextInput.text }
}
属性特性
属性是QML对象的一种特性,它即可以被赋予静态值,也能够绑定一个动态的表达式。其他对象可以读取一个对象的属性,在没有显示拒绝的情况下也能够修改这个对象的某个属性。
属性的定义/属性的声明
在这里属性的定义和属性的声明是相同的意思。
通过以下方法在QML文档里对象类型声明中声明一个自定义的属性。
[default] property
这种方式的对象声明把某些特殊值暴露给外部的对象或容易地维护内部状态。
属性名必须以小写字母或下划线开头,并且不能包含非字母,数字或下划线的字符。Javascript保留字不是合法的属性名。关键字default是可选的。
声明一个自定义属性的同时隐式地为该属性创建一个值改变信号以及一个关联的信号处理器onChanged,第一个字母要大写。
如下所示,下面的对象声明继承基类型的基础上定义了一个新的Retangle类型,它有两个新的属性和一个信号处理器:
Rectangle {
property color previousColor
property color nextColor
onNextColorChanged: console.log("The next color will be: " + nextColor.toString())
}
自定义属性中合法的类型
除了枚举类型外,所有的QML基本类型都可以作为自定义属性的类型。例如,下面都是合法的属性声明:
Item {
property int someNumber
property string someString
property url someUrl
}
枚举值就是一个整数数字,因此可以使用int类型来替代。
有些基本类型是由QtQuick模块提供的,使用前必须将该模块导入。
var类型是通用类型,能够保存包括list类型和object类型在内的所有类型的值。
property var someNumber: 1.5
property var someString: "abc"
property var someBool: true
property var someList: [1, 2, "three", "four"]
property var someObject: Rectangle { width: 100; height: 100; color: "red" }
此外,QML对象类型也能够作为属性的类型:
property Item someItem
property Rectangle someRectangle
如果是一个自定义类型,它也可以作为属性的类型。
属性的赋值
赋值是指为属性指定一个值。
有两种方式给对象的属性赋值:
? 声明式赋值(属性绑定)
? 指令式赋值
初始化赋值
在定义属性时使用绑定进行初始化:
[default] property :
例子:
import QtQuick 2.0
Rectangle {
color: "red"
property color nextColor: "blue" // 属性定义时初始化
}
指令赋值
使用JavaScript指令代码"="操作符为属性赋值:
[.] = value
例子:
import QtQuick 2.0
Rectangle {
id: rect
Component.onCompleted: {
rect.color = "red"
}
}
属性绑定:
绑定,是一个常量值或表达式值。属性绑定是属性的声明式赋值方式,指把属性绑定到一个值上。
属性绑定的语法:属性名和绑定值之间用冒号分隔
:
属性绑定的例子:
import QtQuick 2.0
Rectangle {
// 绑定静态值
width: 400
height: 200
Rectangle {
//绑定表达式
width: parent.width / 2
height: parent.height
}
}
绑定值可以静态值或常量值,也可以是一个描述属性与其他属性依赖关系的Javascript表达式,后者也称作绑定表达式。绑定表达式中的变量称为该属性的依赖。QML引擎维护属性与其依赖的关系。即当任何依赖的值发生改变时,QML引擎会自动的重算绑定表达式的值并将结果赋值给属性。
绑定值可以是QML基本类型,也可以是其他元素包括对象的属性,函数或JavaScript对象等。
属性在任何时刻只能有一个值,为已经绑定的属性赋值会移除它的绑定。
类型安全
属性是类型安全的,一个属性仅能接受与它相同类型的值。
property int volume: "four" // 发生错误,该对象无法加载,int类型的属性不能赋给字符串值
同样,如果在程序运行时给属性赋予不同类型的值时,赋值不成功且产生一个错误。
有些属性的类型没有自然值的表现形式,对于这些类型QML引擎自动地执行字符串到该类型值的转换。例如,color类型保存的是颜色值而非字符串值,但你也能够将字符串"red"赋值到一个color类型的属性而不会出现任何错误。
特殊的属性类型
对象列表属性
对象列表类型的属性接收一个QML对象的列表,一个对象列表值是由方括号括起来的用逗号分隔对象的列表:
[ - ,
- , ... ]
例子:Item类型有一个states属性,用来保存一个State对象的列表
import QtQuick 2.0
Item {
states: [
State { name: "loading" },
State { name: "running" },
State { name: "stopped" }
]
}
如果列表仅有一个对象,则方括号可以省略:
import QtQuick 2.0
Item {
states: State { name: "running" }
}
在对象声明中定义一个指定对象列表类型的属性:
[default] property list propertyName
与其他类型的属性声明一样,可以在列表属性声明时结合初始化赋值操作:
[default] property list > propertyName:
例子:
import QtQuick 2.0
Rectangle {
// 无初始化的属性声明
property list siblingRects
// 有初始化的属性声明
property list childRects: [
Rectangle { color: "red" },
Rectangle { color: "blue"}
]
}
QML中list类型只能储存QML对象,若要储存基本类型的值到list中则应该声明为var类型。
property var myList: []
对列表的内容进行操作不会自动触发myListChanged()信号,如果要捕捉列表的变化则要显式触发该属性变化信号。
组属性
有时候,属性包含一组子属性,这样的属性叫作组属性。组属性的子属性使用点符号或组符号来赋值。
例子:
Text {
//dot notation
font.pixelSize: 12
font.b: true
}
Text {
//group notation
font { pixelSize: 12; b: true }
}
例子中,font是text的组属性。组属性的类型是QML语言中带有子属性的类型。这些类型有些是QML本身的基本类型,有些则需由模块QtQuick导入的。
属性的别名
别名属性是特殊的属性,一般的属性定义会新分配一个唯一的存储空间,而别名属性定义则是连接到已定义的属性上,是对其他属性的引用。
别名属性的声明:
[default] property alias :
一个别名仅能引用它所在类型名字空间中的对象或对象属性。别名不能包含JavaScript并且不能引用它所在类型外部的对象。在声明别名时,它的引用对象alias reference是必须要提供的。
例子:
import QtQuick 2.0
Rectangle {
property alias buttonText: textItem.text
width: 100; height: 30; color: "yellow"
Text { id: textItem }
}
buttonText引用到Text对象的text属性上。对buttonText的会导致textItem.text的变化。
别名只有在它所处的整个对象组件完全实例化后才能使用,否则会发生错误。
property alias widgetLabel: label
//will generate an error
//widgetLabel.text: "Initial text"
//will generate an error
//property alias widgetLabelText: widgetLabel.text
Component.onCompleted: widgetLabel.text = "Alias completed Initialization"
别名可以与存在的其他属性重名。
例子:
Rectangle {
id: coloredrectangle
property alias color: bluerectangle.color
color: "red"
Rectangle {
id: bluerectangle
color: "#1234ff"
}
Component.onCompleted: {
console.log (coloredrectangle.color) //prints "#1234ff"
setInternalColor()
console.log (coloredrectangle.color) //prints "#111111"
coloredrectangle.color = "#884646"
console.log (coloredrectangle.color) //prints #884646
}
//internal function that has access to internal properties
function setInternalColor() {
color = "#111111"
}
}
在这种情况下,外部对象对该类型color属性的使用就是对它所引用的属性的使用,但是在这个类型的内部color属性的使用则是对一般属性而别名属性的使用。
默认属性
每个对象定义可以有一个默认的属性,即在对象内部声明一个新对象时,无需指出子对象被赋给的属性。
// MyLabel.qml
import QtQuick 2.0
Text {
default property var someText
text: "Hello, " + someText.text
}
MyLabel {
Text { text: "world!" }
}
相当于:
MyLabel {
someText: Text { text: "world!" }
}
属性someText被标记为默认属性,因此就不必显示地把对象text赋给这个属性。因为基于类型Item的对象默认属性是children,因此它的孩子对象都会自动地添加到这个属性里。
只读属性
使用关键字readonly声明只读属性:
readonly property :
只读属性必须在初始化的时候赋值。只读属性一旦被初始化,就不能赋给任何值。
Item {
readonly property int someNumber: 10
Component.onCompleted: someNumber = 20 // 错误,someNumber不能再赋值
}
只读属性不能作为默认属性或别名属性。
属性修改器对象
属性可以关联一个属性值修改器对象。声明一个修改器对象实例的语法:
on {
// attributes of the object instance
}
指定修改器对象的类型名字。
指定修改器对象关联的属性名字。
修改器对象必须关联到已存在的属性。某些修改器类型只作用在特定的属性类型,但这并不被QML语言强制执行。例如修改器类型NumberAnimation仅在数值类型(int或者real)的属性上工作,如果把它应用在其他类型上也不会产生错误,只是不起作用罢了。属性修改器的行为由它的实现定义。
信号与信号处理器特性
信号与信号处理器机制是程序和用户界面组件之间的通信方式。信号是触发的事件,对事件作出响应的是信号处理器。
任何时刻事件发生时对象获得通知,相应的信号处理器就会被调用。事件包括属性改变、动画开始或停止、图片下载完成以及用户输入等等。
信号处理器的语法:
on {
// attributes of the object instance
}
是信号的名字,首字母要大写。
信号处理器必须声明在发射该信号的对象定义中。信号处理器的行为由实现的JavaScript代码块指定。
例子:
import QtQuick 2.0
Item {
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Click!")
}
}
}
在对象MouseArea上点击时,对象便会发射clicked信号,与其对应的信号处理器onClicked就会执行。
自定义信号的语法:
signal [([ [, ...]])]
signal是信号声明关键字
是信号的名字
[([ [, ...]])]是指定信号携带的参数类型及参数名
在同一个对象声明中定义两个同名的信号会发生错误。但是可以使用对象类型中已经存在的信号名,注意这会隐藏原先的信号使其变得不可用。
信号定义的例子:
import QtQuick 2.0
Item {
signal clicked
signal hovered()
signal actionPerformed(string action, var actionResult)
}
如果信号没有参数,括号可以省略;如果带有参数,则必须声明参数类型。
信号发射时,信号处理器使用已定义好的信号参数名来访问各自的参数。
信号参数的例子:
import QtQuick 2.0
Rectangle {
id: rect
width: 100; height: 100
MouseArea {
anchors.fill: parent
onClicked: {
rect.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1);
// access 'mouse' parameter
console.log("Clicked mouse at", mouse.x, mouse.y)
}
}
}
查看MouseArea的文档,可以知道clicked信号带有一个名字为mouse的参数,它是类型为MouseEvent的对象,包含有关于鼠标点击事件的详细信息。可以在信号处理器onClicked中引用这个名字来访问相关参数。
属性变化信号处理器
属性变化信号处理器接收QML对象属性值改变时发射信号,这信号的类型是属性变化信号类型。
属性变化信号处理器声明语法:
onChanged {
// attributes of the object instance
}
是属性的名字,首字母要大写。
属性变化信号处理器的例子:
import QtQuick 2.0
Rectangle {
id: rect
width: 100; height: 100
MouseArea {
anchors.fill: parent
onPressedChanged: {
console.log("Mouse area is pressed?", pressed)
}
}
}
pressed是类型MouseArea的一个属性,它的属性变化信号处理器名字就是onPressedChanged。
QML为每个属性隐式地创建空的属性变化信号处理器。
发射信号的方式与调用普通的方法相同。
阅读(25898) | 评论(0) | 转发(0) |