上一章我们介绍了 QML 中用于定位的几种元素,被称为定位器。除了定位器,QML 还提供了另外一种用于布局的机制。我们将这种机制成为锚点(anchor)。锚点允许我们灵活地设置两个元素的相对位置。它使两个元素之间形成一种类似于锚的关系,也就是两个元素之间形成一个固定点。锚点的行为类似于一种链接,它要比单纯地计算坐标改变更强。由于锚点描述的是相对位置,所以在使用锚点时,我们必须指定两个元素,声明其中一个元素相对于另外一个元素。锚点是Item元素的基本属性之一,因而适用于所有 QML 可视元素。

一个元素有 6 个主要的锚点的定位线,如下图所示:

这 6 个定位线分别是:topbottomleftrighthorizontalCenterverticalCenter。对于Text元素,还有一个baseline锚点。每一个锚点定位线都可以结合一个偏移的数值。其中,topbottomleftright称为外边框;horizontalCenterverticalCenterbaseline称为偏移量。

下面,我们使用例子来说明这些锚点的使用。首先,我们需要重新定义一下上一章使用过的BlueRectangle组件:

BlueRectangle

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
import QtQuick 2.0
 
Rectangle {
    width: 48
    height: 48
    color: "blue"
    border.color: Qt.lighter(color)
 
    MouseArea {
        anchors.fill: parent
        drag.target: parent
    }
}

简单来说,我们在BlueRectangle最后增加了一个MouseArea组件。前面的章节中,我们简单使用了这个组件。顾名思义,这是一个用于处理鼠标事件的组件。之前我们使用了它处理鼠标点击事件。这里,我们使用了其拖动事件。anchors.fill: parent一行的含义马上就会解释;drag.target: parent则说明拖动目标是parent。我们的拖动对象是MouseArea的父组件,也就是BlueRectangle组件。

接下来看第一个例子:

代码如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
        BlueRectangle {
            width: 12
            anchors.fill: parent
            anchors.margins: 8
        }
    }
}

在这个例子中,我们使用anchors.fill设置内部蓝色矩形的锚点为填充(fill),填充的目的对象是parent;填充边距是 8px。注意,尽管我们设置了蓝色矩形宽度为 12px,但是因为锚点的优先级要高于宽度属性设置,所以蓝色矩形的实际宽度是 100px – 8px – 8px = 84px。

第二个例子:

代码如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
        BlueRectangle {
            width: 48
            y: 8
            anchors.left: parent.left
            anchors.leftMargin: 8
        }
    }
}

这次,我们使用anchors.left设置内部蓝色矩形的锚点为父组件的左边线(parent.left);左边距是 8px。另外,我们可以试着拖动蓝色矩形,看它的移动方式。在我们拖动时,蓝色矩形只能沿着距离父组件左边 8px 的位置上下移动,这是由于我们设置了锚点的缘故。正如我们前面提到过的,锚点要比单纯地计算坐标改变的效果更强,更优先。

第三个例子:

代码如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
        BlueRectangle {
            width: 48
            anchors.left: parent.right
        }
    }
}

这里,我们修改代码为anchors.left: parent.right,也就是将组件锚点的左边线设置为父组件的右边线。效果即如上图所示。当我们拖动组件时,依然只能上下移动。

下一个例子:

代码如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
 
        BlueRectangle {
            id: blue1
            width: 48; height: 24
            y: 8
            anchors.horizontalCenter: parent.horizontalCenter
        }
        BlueRectangle {
            id: blue2
            width: 72; height: 24
            anchors.top: blue1.bottom
            anchors.topMargin: 4
            anchors.horizontalCenter: blue1.horizontalCenter
        }
    }
}

这算是一个稍微复杂的例子。这里有两个蓝色矩形:blue1blue2blue1的锚点水平中心线设置为父组件的水平中心;blue2的锚点上边线相对于blue1的底部,其中边距为 4px,另外,我们还增加了一个水平中线为blue1的水平中线。这样,blue1相对于父组件,blue2相对于blue1,这样便决定了三者之间的相对关系。当我们拖动蓝色矩形时可以发现,blue1blue2的相对位置始终不变,因为我们已经明确指定了这种相对位置,而二者可以像一个整体似的同时上下移动(因为我们没有指定其中任何一个的上下边距与父组件的关系)。

另外一个例子:

代码如下所示:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
 
        BlueRectangle {
            width: 48
            anchors.centerIn: parent
        }
    }
}

与第一个例子类似,我们使用的是anchors.centerIn: parent将蓝色矩形的中心固定在父组件的中心。由于我们已经指明是中心,所以也不能拖动这个蓝色矩形。

最后一个例子:

代码如下:

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import QtQuick 2.0
 
Rectangle {
    id: root
    width: 220
    height: 220
    color: "black"
 
    GreenRectangle {
        x: 10
        y: 10
        width: 100
        height: 100
 
        BlueRectangle {
            width: 48
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.horizontalCenterOffset: -12
            anchors.verticalCenter: parent.verticalCenter
        }
    }
}

上一个例子中,anchors.centerIn: parent可以看作等价于anchors.horizontalCenter: parent.horizontalCenteranchors.verticalCenter: parent.verticalCenter。而这里,我们设置了anchors.horizontalCenterOffset为 -12,也就是向左偏移 12px。当然,我们也可以在anchors.centerIn: parent的基础上增加anchors.horizontalCenterOffset的值,二者是等价的。由于我们在这里指定的相对位置已经很明确,拖动也是无效的。

至此,我们简单介绍了 QML 中定位器和锚点的概念。看起来这些元素和机制都很简单,但是,通过有机地结合,足以灵活应对更复杂的场景。我们所要做的就是不断熟悉、深化对这些定位布局技术的理解。

Qt 学习之路:元素布局的更多相关文章

  1. Qt 学习之路 2(11):布局管理器

    Home / Qt 学习之路 2 / Qt 学习之路 2(11):布局管理器 Qt 学习之路 2(11):布局管理器  豆子  2012年9月4日  Qt 学习之路 2  70条评论 所谓 GUI 界 ...

  2. Qt 学习之路 2(12):菜单栏、工具栏和状态栏

    Home / Qt 学习之路 2 / Qt 学习之路 2(12):菜单栏.工具栏和状态栏 Qt 学习之路 2(12):菜单栏.工具栏和状态栏  豆子  2012年9月10日  Qt 学习之路 2  2 ...

  3. 《Qt 学习之路 2》目录

    <Qt 学习之路 2>目录 <Qt 学习之路 2>目录  豆子  2012年8月23日  Qt 学习之路 2  177条评论 <Qt 学习之路 2>目录 序 Qt ...

  4. Qt学习之路

      Qt学习之路_14(简易音乐播放器)   Qt学习之路_13(简易俄罗斯方块)   Qt学习之路_12(简易数据管理系统)   Qt学习之路_11(简易多文档编辑器)   Qt学习之路_10(Qt ...

  5. Qt 学习之路 2(76):QML 和 QtQuick 2

    Home / Qt 学习之路 2 / Qt 学习之路 2(76):QML 和 QtQuick 2 Qt 学习之路 2(76):QML 和 QtQuick 2  豆子  2013年12月18日  Qt ...

  6. Qt 学习之路 2(60):使用 DOM 处理 XML

    Qt 学习之路 2(60):使用 DOM 处理 XML  豆子  2013年8月3日  Qt 学习之路 2  9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...

  7. Qt 学习之路 2(59):使用流处理 XML

    Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...

  8. Qt 学习之路 2(51):布尔表达式树模型

    Qt 学习之路 2(51):布尔表达式树模型 豆子 2013年5月15日 Qt 学习之路 2 17条评论 本章将会是自定义模型的最后一部分.原本打算结束这部分内容,不过实在不忍心放弃这个示例.来自于 ...

  9. Qt 学习之路 2(46):视图和委托

    Home / Qt 学习之路 2 / Qt 学习之路 2(46):视图和委托 Qt 学习之路 2(46):视图和委托  豆子  2013年3月11日  Qt 学习之路 2  63条评论 前面我们介绍了 ...

  10. Qt 学习之路 2(45):模型

    Home / Qt 学习之路 2 / Qt 学习之路 2(45):模型 Qt 学习之路 2(45):模型  豆子  2013年2月26日  Qt 学习之路 2  23条评论 在前面两章的基础之上,我们 ...

随机推荐

  1. AppDomain与进程、线程、Assembly之间关系

    AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序 AppDomain是CLR实现代码隔离的基本机制.   每一个AppDomain可以单独运行.停止:每个AppD ...

  2. linux平台上面python调用c

    不能免俗,先打印个helloworld出来,c代码的函数 hello.c #include <stdio.h> int helloworld() { printf("hello ...

  3. Linux Kernel Makefile Test

    一.本文说明 本文为linux内核Makefile整体分析的续篇,是依据Linux内核Makefile体系的主要内容编写一个简要的测试工程.Linux内核Makefile体系就好像一只“大鸟”,而这篇 ...

  4. jsp表单提交中文乱码的解决

    <%@ page language="Java" contentType="text/html; charset=utf-8 "    pageEncod ...

  5. Struts_json插件配置参数

    Struts中使用json需要在struts基础上加上几个包:(这里只列出了重要的几个) commons-lang-2.4.jar: jsonplugin-0[1].32.jar: 下面是配置文件中的 ...

  6. bzoj 3041: 水叮当的舞步 迭代加深搜索 && NOIP RP++

    3041: 水叮当的舞步 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 72  Solved: 44[Submit][Status] Descript ...

  7. 【POJ2699】The Maximum Number of Strong Kings(网络流)

    Description A tournament can be represented by a complete graph in which each vertex denotes a playe ...

  8. keil C51中建立多文件时,变量重复定义的解决

    c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下. 对于比较小的程序,一般只有一个c文件和一个头文件,全局变量 ...

  9. SCP和SFTP(都使用SSH。但SCP上传不能中断,而SFTP可以续传,这是最大区别)

    不管SCP还是SFTP,都是SSH的功能之一.都是使用SSH协议来传输文件的. 不用说文件内容,就是登录时的用户信息都是经过SSH加密后才传输的,所以说SCP和SFTP实现了安全的文件传输. SCP和 ...

  10. iso学习网站记录

    [零基础学习iOS开发] http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 非零基础学习iOS开发2-Objective-C h ...