标签:qml qt on android qt quick javascript
在《Qt on Android:Qt Quick 简介》中我们提到 QML 语法和 Json 类似,请参考《Qt on Android: http下载与Json解析》查看 Json 语法。当然这里我们是期望从零开始也能学会 QML ,所以呢,你也可以直接往下看。
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;
}
}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 on Android: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;
}
}上面的示例中,退出按钮使用 id( openFile )引用了打开按钮。
我的乖呀,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 " 为关键字检索,找到 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; }
}属性真难搞!到现在还没讲完,不但你烦了,我也快坐不住了。我保证,这是最后一个要点了,不过也是最复杂最难以理解的属性了。对于这种玩意儿,我一向的做法时,不能理解的话就接受,你就当它生来如此,存在即合理,只要学会怎么用它就 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");
}最后说下 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;
}
}
}好啦,关于 QML 语言的基础性介绍就到这里,相信现在你已经可以看懂简单的 QML 文档了。有的同学可能又疑问了,这节还有一些东东只见用不见讲啊,比如 Rectangle / Text / Image / Item / Button / Component / Qt 等等,抱歉,现在只能揣着糊涂装明白了,下一篇我们会讲这些东西。
Qt on Android:QML 语言基础,布布扣,bubuko.com
标签:qml qt on android qt quick javascript
原文地址:http://blog.csdn.net/foruok/article/details/28634543