Overview
- QML(Qt Meta Language),自Qt4.7引入。
- Qt Quick是Qt为QML提供的一套类库,由QML标准类型和功能组成,包括可视化类型、交互类型、动画类型、模型和视图、粒子系统和渲染效果等。
- 每个QML文档都由import和对象声明构成。
QML Syntax
Profile:
- QML是一种描述用户界面的声明式语言。
- 子元素从父元素上继承了坐标系统,它的x,y坐标总是相对应于它的父元素坐标系统。
- 每一个QML文件都需要一个根元素,就像HTML一样。
- 一个元素使用它的类型声明,然后使用{}进行包含。
- 元素拥有属性,他们按照
name:value
的格式来赋值。 - 任何在QML文档中的元素都可以使用它们的id进行访问(
id
是一个任意的标识符)。 - 元素可以嵌套,这意味着一个父元素可以拥有多个子元素。子元素可以通过访问
parent
关键字来访问它们的父元素。有一个比较好的方法是命名你的根元素对象id为root(id:root),这样就不用去思考你的QML文档中的根元素应该用什么方式命名了。
Properties:
-
对象和属性:
-
每个QML文档(文件)有且只有一个跟对象。
-
对象由类型它们的类型指定,以大写字母开头,后面跟一对大括号。
-
对象的属性在括号中,以键值对的形式出现。
-
一个属性能够设置一个值,这个值依赖于它的类型。如果没有对一个属性赋值,那么它将会被初始化为一个默认值。(具体看帮助文档)。
-
QML允许将多个属性写在一行,但是它们之间必须用分号隔开。
-
{ width: 300 height: 300 } //或者 { width: 300; height: 300 }
-
一个属性能够依赖一个或多个其它的属性,这种操作称作属性绑定。当它依赖的属性改变时,它的值也会更新。
-
使用
property
修饰符自定义属性,然后跟上类型、名字和可选择的初始化值。如果没有初始值将会给定一个系统初始值作为初始值。注意如果属性名与已定义的默认属性名不重复,使用default关键字你可以将一个属性定义为默认属性。这在你添加子元素时用得着,如果他们是可视化的元素,子元素会自动的添加默认属性的子类型链表(children property list)。
-
-
对象标识符:
id
是一个非常特殊的属性值,它可以作为一个标识符在当前文档内引用对应的元素。id
不是一个字符串,而是一个标识符和QML语法的一部分。id
在一个QML文档中是唯一的,并且不能被设置为其它值,也无法被查询(像C++里的指针)。id
值必须使用小写字母或下划线开头,并且不能使用除字母、数字和下划线以外的字符。
-
属性别名:
alias
-
作用:属性别名允许外部对象(其他QML文件)直接修改和访问本QML文档中的子对象。
-
它可以将内部嵌套的QML元素的属性导出到外面使用;注意,只有根级目录的属性才能够被其它文件的组件访问。
-
例如:
//other.qml Xxx { ... mouseArea.OnClicked: { console.log("external mouseArea clicked!"); } ... } //internal.qml Rectangle { property alias mouseArea: mouseArea //MouseArea的属性别名 ... MouseArea { id: mouseArea ... } }
-
如果你想使用命令行的方式构建Qt5,你首先需要拷贝一个代码库并构建它:
-
git clone git://gitorious.org/qt/qt5.git cd qt5 ./init-repository ./configure -prefix $PWD/qtbase -opensource make -j4
-
如果你想测试你的编译,只需简单的启动
qtbase/bin/qmlscene
并且选择一个QtQuick的例子运行: -
qtbase/bin/qmlscene xxxx.qml
-
-
关于属性其他的点:
- 一些属性是元素自身的附加属性。这样做是为了全局的相关元素在应用程序中只出现一次(例如键盘输入:
KeyNavigation.tab: otherLabel
)。 - 对于每个属性都可以提供一个信号操作。这个信号在属性值改变时被发送。
- 一些属性是元素自身的附加属性。这样做是为了全局的相关元素在应用程序中只出现一次(例如键盘输入:
-
警告:一个元素id应该只在当前文档中被引用。QML提供了动态作用域的机制,后加载的文档会覆盖之前加载文档的元素id号
QML与JavaScript
-
QML的:
=
(属性绑定)与JavaScript的=
(赋值)是不同的。 -
绑定是一个协议,并且存在于整个生命周期。
-
然而JavaScript赋值(=)只会产生一次效果。当一个新的绑定生效或者使用JavaScript赋值给属性时,绑定的生命周期就会结束。
-
举个例子:
-
Text { id: text properry int pressedTimes: 0 text: "xxxxxx" + pressedTimes //每次按下空格后都会改变显示的值(属性绑定) Keys.onSpacePressed: { pressedTimes += 1; } //按下ESC键后,再按空格也不会显示增加的次数了。 Keys.onEscapePressed: { text.text = ''; } }
-
类似于这个例子,最好不要使用绑定属性。可使用赋值的方式来改变属性,属性绑定会在赋值操作(
=
)后被销毁(broken contract)。
Visual Elements
- QML语言使用可视元素来描述图形化的用户界面,每个可视元素都是一个对象,具有几何坐标,在屏幕上占据一块显示区域。
- Item(基础元素对象)是所有可视化元素的基础对象,所有其它的可视化元素都继承自Item。它自身不会有任何绘制操作,但是定义了所有可视化元素共有的属性。
- Item(基本元素对象)通常被用来作为其它元素的容器使用,类似HTML语言中的div元素(div element)。
Rectangle
- 属性
color
的默认指定颜色是来自SVG颜色的名称:CSS Color Module Level 3 (w3.org) gradient
属性可以指明渐变:ConicalGradient
:锥形渐变;LinearGradient
:线性渐变;ConicalGradient
:原型渐变;
- 如果没有设置布局之类的,记得要指定宽和高,不然默认都是0导致矩形不可见;
Image
source
属性的值可以是:- 远程URL;
- 本地URL;
- 嵌入已编译资源文件中的URL;
- 可以设置父类的
clip
属性为true
,防止渲染的图片超出元素范围;这对任何可视化元素都是有效的。 - 或者设置图片的
fillMode
:fillMode: Image.PreserveAspectCrop
;
Text
- 这个元素会使用给出的
text
与font
来计算初始化的宽度与高度,默认未给出则使用parent
; width
属性如果给出则会限制宽度,默认自动计算;- 为了提高文本的渲染效果,可以使用
style
和styleColor
属性来配置文字的外框效果,浮雕效果或者凹陷效果。 elide
属性设置文本左边,右边或者中间的省略位置。wrapMode
属性:使用文字换行的方式显示所有的文本,该属性只在明确设置了宽度后才生效;可设置为Text.WordWrap
只在单词边界换行。textFormat
属性可设置文本格式,默认为富文本格式;Qt5.14后可支持Text.MarkdownText
。
Custom Components
- 可使用自定义创建的组件来重复使用;
- 使用了QML的alias(别名)的功能,它可以将内部嵌套的QML元素的属性导出到外面使用。有一点很重要,只有根级目录的属性才能够被其它文件的组件访问。
- 一般将
Item
作为root组件,防止用户改变内部的一些属性,并且可以提供出更多相关控制的API(应用程序接口)。
Layout
Positioner
Row
、Column
、Grid
、Flow
都包含在QtQuick模块中;- 流定位
Flow
:- 为了让一个
Flow
可以工作,必须指定一个宽度或者高度,可以通过属性直接设定,或者通过anchor(锚定)布局设置。
- 为了让一个
- 重复器
Repeater
:- 通常Repeater(重复元素)与定位器一起使用。
- 当有一小部分的静态数据需要显示时,使用重复器是最好的方式。
- 高级的大数据模型处理和使用动态代理的动态视图使用模型与视图(model-view)。
Anchor
- 可以使用
xxx.anchors.left = undefined
来解除锚点属性的定义; - 在编程布局中,一定要先将元素的旧锚接触,新设置的才能生效(QtQuick 1)
事件处理
鼠标事件
- 使用
drag
设置拖拽属性; mouse.button
获取按下的键,要设置acceptedButtons
:(可以使用|
组合设置)Qt.LeftButton
:鼠标左键Qt.MiddleButton
:鼠标中键Qt.RightButtons
:鼠标右键
mouse.modifiers
获取鼠标和键盘的组合形式,然后进行判断,例如:if (mouse.modifiers & Qt.ShiftModifier)
mouse.modifiers
的值可能由多个按键进行位组合而成,详细可参考文档。
键盘事件
focus
属性表面当前组件是否被选中;KeyNavigation
(按键向导)附加属性可以预先设置一个元素id绑定切换焦点的按键。- 它的子属性有
backtab
down
left
priority
right
tab
up
。 - 可以使用这些来设置焦点转移。
- 例如:
KeyNavigation.tab: xxx_ID
表示在这个控件中按下Tab
键后焦点转移到id为xxx_ID
的控件上。
- 它的子属性有
- 使用
Keys
的附加属性可以处理按下按键之后的事件,例如:Keys.onLeftPressed: xxx_ID.y += 10
表示按下方向键后移动位置。
输入控件与焦点
TextInput
:- QML本身提供的元素,只有光标和文本内容,无边框。
- 这个元素支持使用正则表达式验证器来限制输入和输入掩码的模式设置。
validator
、inputMask
、echoMode
。
TextEdit
:- 和
TextInput
类似,多行的文本编辑组件。 - 它不再支持文本输入的限制,但是提供了已绘制文本的大小查询(
paintedHeight
,paintedWidth
)。
- 和
FocusScope
- 可以将自定义的组件置于
FocusScope
中,因为这样能有效地控制焦点。 - 假如控件中有很多子元素,在程序运行时,父元素不会主动将焦点转移给子元素;为了解决这一问题,QML专门提供了
FocusScope
,它在接收到焦点时,会将焦点交给最后一个设置了focus: true
的子对象。 - 这样子元素需要焦点时,则不会被父元素所夺取。
- 例如Row中有Text和Rectangle,Rectangle为输入元素
TextInput
的边框。
QML导入JS函数
- 将js文件添加到qt的资源文件后,在要使用QML文件中导入:
import "myscript.js" as Xxxxx
- 然后使用:
Xxxxx.xx();