标签:
在《Qt Quick 简单介绍》中我们提到 QML 语法和 Json 相似,请參考《Qt on Android: http下载与Json解析》查看 Json 语法。当然这里我们是期望从零開始也能学会 QML ,所以呢,你也能够直接往下看。
版权全部 foruok,转载请注明出处:http://blog.csdn.net/foruok
QML 文件的后缀是 qml ,事实上就是个文本文件。以下是 一个简单的 QML 文件:
import QtQuick 2.0 import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import an.qt.ImageProcessor 1.0 import QtQuick.Controls.Styles 1.1 Rectangle { width: 320; height: 480; color: "#121212"; Image { source: "images/IMG_001.jpg"; anchors.centerIn: parent; } }
接着废话吧。
import 和 C++ 中的 #include 相似。与 Java 中的 import 效果一样。与 JavaScript 中的……唐僧了,打住。
Rectangle{ } 语句。定义了一个类型为 Rectangle 的对象。
假设你看了《Qt on Android: http下载与Json解析》一文中有关 Json 的语法描写叙述。应该已经知道对象要用一对花括号来描写叙述。没错。 QML 里也是这样,只是呢,花括号前要写上对象的类型。就这么简单!
演示样例 QML 文档中有两个对象。一个是 Rectangle 。一个是 Image 。
在花括号之间,是对象的属性描写叙述(还能够有其他的,后面再说)。属性是以 "property: value" 形式指定的,这点和 Json 一样。
如你所见, Rectangle 对象有 width 、 color 等属性。
属性能够分行书写。此时语句后能够不要 ";" 号,只是笔者建议 C++ 程序员都加上 ";" ,这会避免你患上精神分裂症。
当然,也能够把多个属性写在一行内,多个属性之间必须以 ";" 切割。例如以下所看到的:
Rectangle { width: 320; height: 480; color: "#121212"; }我强烈建议你不要这么干!除非有代码意外的原因,比方排版须要。比方老板认为你代码行数太多……
在《Qt Quick 简单介绍》中笔者已经提到。 QML 支持 JavaScript 表达式。
比方你能够这样改写 Rectangle 对象的宽、高属性:
Rectangle { width: 23*10; height: 6*80; color: "#121212"; }
Button { text: "Quit"; style: ButtonStyle { background: Rectangle { implicitWidth: 70; implicitHeight: 25; border.width: control.activeFocus ?2 : 1; } } }
另外,慧眼如你,可能已经注意到。上面的表达式中我使用了 "control.activeFocus" ,没错,在表达式中能够引用其他对象及其属性。当你这么做的时候。待赋值的属性就和你所引用的对象的那个属性建立了关联,当被引用属性发生变化时。表达式的值会又一次计算。而待赋值的属性也会变化。
或许你心中已经有了疑问:怎样引用一个对象呢?答案是:通过对象的 id 值来引用一个对象。看这里:
Rectangle { width: 320; height: 480; Button { id: openFile; text: "打开"; anchors.left: parent.left; anchors.leftMargin: 6; anchors.top: parent.top; anchors.topMargin: 6; } Button { id: quit; text: "退出"; anchors.left: openFile.right; anchors.leftMargin: 4; anchors.bottom: openFile.bottom; } }
上面的演示样例中,退出button使用 id( openFile )引用了打开button。
我的乖呀,anchors 是什么东东……先别管它,下一篇会讲到。
在 QML 中。凝视与 C++ 中一样,单行以 "//" 開始。多行以 "/*" 開始以 "*/" 结束。
凝视是不被运行的,加入凝视可对代码进行解释或者提高其可读性。凝视相同还可用于防止代码运行,这对跟踪问题是非常实用的。
使用凝视的演示样例 QML :
/* * the root element of QML */ Rectangle { width: 320; height: 480; Button { id: quit; text: "退出"; //use anchors to layout anchors.left: openFile.right; anchors.leftMargin: 4; anchors.bottom: openFile.bottom; //set z-order z: 1; } }
事实上, QML 中的属性。就是我们非常熟悉的 C++ 中的成员变量……
属性名的首字母一般以小写開始,如我们看烦了的 width 属性。
假设属性名以多个单词表示,那么第二个及以后的单词,首字母大写。
能够在 QML 文档中使用的类型大概有三类:
我们先看 QML 语言提供的基本类型。
QML 支持的基本类型包括整型、实数型、布尔、字符串、颜色、列表等等。
这些基本类型有些是和 JavaScript 语言的基本类型相应的。
还是之前的演示样例,改动了一下,通过凝视标注了属性类型:
Rectangle { width: 320; //int height: 480; Button { id: quit; text: "退出"; //string anchors.left: openFile.right; anchors.leftMargin: 4; anchors.bottom: openFile.bottom; z: 1.5; // real visible: false; //bool } }
请使用 Qt 助手的索引模式。以"qml basic types " 为keyword检索。找到 QML Basic Types 页面来查看完整的类型列表和每个类型的详情。
Qt 的 QML 模块还未 QML 引入的非常多 Qt 相关的类型,如 Qt 、 QtObject 、Component 、 Connections 、 Binding 等,请使用 Qt 助手检索 "qt qml qml types" 来了解。
之前在介绍表达式时提到了 id 属性,这里展开描写叙述一下。
一个对象的 id 属性是唯一的,在同一个 QML 文件里不同对象的 id 属性的值不能反复。当给一个对象指定了 id ,就能够在其他对象或脚本中通过 id 来引用该对象。
在“表达式”一节中我们已经演示了怎样通过 id 来引用一个对象。
请注意, id 属性的值,首字符必须是小写字母或下划线而且不能包括字母、数字、下划线以外的字符。
列表属性相似于以下这样:
Item { children:[ Image{}, Text{} ] }
[ "name":"zhangsan", { "age":30, "phone":"13588888888", "other": ["xian", null, 1.0, 28] } ]
值得注意的是,列表内仅仅能包括 QML 对象,不能包括不论什么基本类型(如整型、布尔型)。这点与 Json 是不一样的。以下是訪问列表的演示样例:
Item { children:[ Text{ text: "textOne"; }, Text{ text: "textTwo"; } ] Component.onCompleted:{ for (var i = 0; i < children.length; i++) console.log("text of label ", i, " : ", children[i].text) } }
假设你一个列表内仅仅有一个元素,也能够省略方括号。例如以下所看到的:
Item { children:Image{} }
只是笔者还是建议你始终使用方括号。哪怕当中仅仅有一个元素。
有没有什么问题?有就要说啊,闷在心里会憋坏自己的。
好吧。你不说我就说了。在我们訪问列表的演示样例中出现了一个新的内容。Component.onCompleted :{} 。这是什么东东呢?接下来我们就来讲它。
信号处理器。事实上等价于 Qt 中的槽。可是我们没有看到相似 C++ 中的明白定义的函数……没错,就是这样。你的的确确仅仅看到了一对花括号!对啦,这是 JavaScript 中的代码块。事实上呢,你能够理解为它是一个匿名函数。
而 JavaScript 中的函数,事实上具名的代码块。
函数的优点是你能够在其他地方依据名字调用它。而代码块的优点是。除了定义它的地方,没人能调用它,一句话,它是私有的。代码块就是一系列语句的组合。它的作用就是使语句序列一起运行。
让我们回头再看信号处理器,它的名字还有点儿特别,通常是 on{Signal} 这样的形式。比方 Qt Quick 中的 Button 元素有一个信号 clicked() ,那么你要可能会写出这样的代码:
Rectangle { width: 320; height: 480; Button { id: quit; text: "退出"; anchors.left: parent.left; anchors.leftMargin: 4; anchors.bottom: parent.bottom; anchors.bottomMargin: 4; onClicked: { Qt.quit(); } } }
你看到了,当信号是 clicked() 时,信号处理器就命名为 onClicked 。就这么简单,以 on 起始后跟信号名字(第一个字母大写)。
在某些情况下使用一个 ‘.‘ 符号或分组符号把相关的属性形成一个逻辑组。分组属性可写以下这样:
Text { font.pixelSize: 18; font.bold: true; }
Text { font { pixelSize: 12; bold: true; } }
对于类型为对象的属性值,能够使用 "." 操作符展开对象的每个成员对其赋值。也能够通过分组符号(一对花括号)把要赋值的成员放在一起给它们赋值。对于后者,其形式就和对象的定义一样了,起码看起来木有差别。所以呢。又能够这么理解上面的演示样例: Text 对象内聚合了 font 对象。 OK ,就是聚合。
属性真难搞!
到如今还没讲完,不但你烦了,我也快坐不住了。我保证。这是最后一个要点了,只是也是最复杂最难以理解的属性了。对于这样的玩意儿,我一向的做法时。不能理解的话就接受。你就当它生来如此,存在即合理,仅仅要学会怎么用它就 OK 了。
在 QML 语言的语法中,有一个附加属性(attached properties)和附加信号处理器(attached signal handlers)的概念,这是附加到一个对象上的额外的属性。从本质上讲,这些属性是由附加类型(attaching type)来实现和提供的,它们可能被附加到另一种类型的对象上。
附加属性与普通属性的差别在于。对象的普通属性是由对象本身或其基类(或沿继承层级向上追溯的祖先们)提供的。
举个样例。以下的 Item 对象使用了附加属性和附加信号处理器:
import QtQuick 2.0 Item { width: 100; height: 100; focus: true; Keys.enabled: false; Keys.onReturnPressed: console.log("Return key was pressed"); }
onReturnPressed 事实上是 Keys 对象的一个信号。对于附加信号处理器,和前面讲到的普通信号处理器又有所不同。
普通信号处理器,你先要知道信号名字。然后依照 on{Signal} 的语法来定义信号处理器的名字;而附加信号处理器。你仅仅要通过附加类型名字引用它。把代码块赋值给它就可以。
最后说下 Keys 对象。它是 Qt Quick 提供的,专门供 Item 处理按键事件的对象。它定义了非常多针对特定按键的信号。比方上面的 onReturnPressed ,还定义了更为普通的 onPressed 和 onReleased 信号,一般地,你能够使用这两个信号来处理按键(请对比 Qt C++ 中的 keyPressEvent 和 keyReleaseEvent 来理解)。
它们有一个名字是 event 的 KeyEvent 參数,包括了按键的具体信息。
假设一个按键被处理。 event.accepted 应该被设置为 true 以免它被继续传递。
以下是使用 onPressed 信号的一个演示样例,它检測了左方向键:
Item { anchors.fill: parent; focus: true; Keys.onPressed: { if (event.key == Qt.Key_Left) { console.log("move left"); event.accepted = true; } } }
版权全部 foruok。转载请注明出处:http://blog.csdn.net/foruok
好啦,关于 QML 语言的基础性介绍就到这里,相信如今你已经能够看懂简单的 QML 文档了。有的同学可能有疑问了。这节另一些东东仅仅见用不见讲啊。比方 Rectangle / Text / Image / Item / Button / Component / Qt 等等,抱歉,如今仅仅能揣着糊涂装明白了。下一篇我们会讲这些东西。
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/5256066.html