QML语法简介

QML 语法和 Json 相似,
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;
    }
}

这个简单的 QML 文件的開始是 import 语句。import 和 C++ 中的 #include 相似。


对象:


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”;
}

表达式 <==> 三目运算符

Button {
    text: "Quit";
    style: ButtonStyle {
        background: Rectangle {
            implicitWidth: 70;
            implicitHeight: 25;
            border.width: control.activeFocus ? 2 : 1;
        }
    }
}

在这个演示样例中我指定了button风格中的背景矩形。在button有焦点时边框宽度为 2 没有焦点时宽度为 1 。语句 “border.width: control.activeFocus ? 2 : 1” 使用了 JavaScript 的 “?:” 三元云算法( C++ 中貌似也有……)。三目运算符
另外,慧眼如你,可能已经注意到。上面的表达式中我使用了 “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;
    }
}

anchors :是QML的一种布局方法,参看QML布局

属性

属性命名
属性名的首字母一般以小写開始,如我们看烦了的 width 属性。

假设属性名以多个单词表示,那么第二个及以后的单词,首字母大写。

属性类型
能够在 QML 文档中使用的类型大概有三类:
由 QML 语言本身提供的类型
使用 QML 模块注冊 C++ 类型
由 QML 模块提供的类型
我们先看 QML 语言提供的基本类型。

1. 基本类型:整型、实数型、布尔、字符串、颜色、列表等等。

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
    }
}
注意。 QML 中属性是有类型安全检測的,也就是说你仅仅能指定与属性类型匹配的值。否则会报错。
请使用 Qt 助手的索引模式。以"qml basic types " 为keyword检索。找到 QML Basic Types 页面来查看完整的类型列表和每个类型的详情。

2. Qt 的 QML 模块

还为 QML 引入的非常多 Qt 相关的类型,如 Qt 、 QtObject 、Component 、 Connections 、 Binding 等,请使用 Qt 助手检索 “qt qml qml types” 来了解。

  1. id 属性
    之前在介绍表达式时提到了 id 属性,这里展开描写叙述一下。
    请注意, id 属性的值,首字符必须是小写字母或下划线而且不能包括字母、数字、下划线以外的字符。

  2. 列表属性

    列表属性相似于以下这样:

Item {
    children:[
        Image{},
        Text{}
    ]
}
列表是包括在方括号内,以逗号分隔的列表元素。看起来是不是挺熟悉?在《Qt on Android: http下载与Json解析》中。我们举过 Json 数组的样例。再看看:
[
  "name":"zhangsan", 
  {
    "age":30,
    "phone":"13588888888",
    "other": ["xian", null, 1.0, 28]
  }
]
事实上列表和 JavaScript 的数组是相似的,其訪问方式也一样:

length 属性提供了列表内元素的个数
列表内的元素通过数组下标来訪问([index])
值得注意的是,列表内仅仅能包括 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 :{} 。参看本文“信号处理器”。

  1. 分组属性

    在某些情况下使用一个 ‘.’ 符号或分组符号把相关的属性形成一个逻辑组。分组属性可写以下这样:

Text {
    font.pixelSize: 18;
    font.bold: true;
}

    也能够这样写:
Text {
    font { pixelSize: 12; bold: true; }
}
事实上呢,能够这么理解。font 属性的类型本身是一个对象,这个对象又有 pixelSize / bold / italic / underline 等等属性。

对于类型为对象的属性值,能够使用 “.” 操作符展开对象的每个成员对其赋值。也能够通过分组符号(一对花括号)把要赋值的成员放在一起给它们赋值。对于后者,其形式就和对象的定义一样了,起码看起来木有差别。所以呢。又能够这么理解上面的演示样例: Text 对象内聚合了 font 对象。 OK ,就是聚合。

  1. 附加属性

到如今还没讲完,不但你烦了,我也快坐不住了。我保证。这是最后一个要点了,只是也是最复杂最难以理解的属性了。对于这样的玩意儿,我一向的做法时。不能理解的话就接受。你就当它生来如此,存在即合理,仅仅要学会怎么用它就 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");
}
你看, Item 对象能够訪问和设置 Keys.enabled 和 Keys.onReturnPressed 的值。 enabled 是 Keys 对象的一个属性。

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;
        }
    }
}

信号处理器

信号处理器。事实上等价于 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();
        }
    }
}

上面的 QML 代码事实上已经是一个简单 QML 应用了,这个应用在窗体的左下角放了个退出button。当用户点击它时会触发button的 clicked() 信号,而我们定义了信号处理器来响应 clicked() 信号——调用 Qt.quit() 退出应用。
你看到了,当信号是 clicked() 时,信号处理器就命名为 onClicked 。就这么简单,以 on 起始后跟信号名字(第一个字母大写)。
参考博文

发布了11 篇原创文章 · 获赞 8 · 访问量 158

猜你喜欢

转载自blog.csdn.net/qq_37730663/article/details/105286861
QML