前言

本节将学习QML的定位器positioners,即Row,Column,Grid,它们分别可以实现水平排列、垂直排列和网格排列,这种布局策略将帮助我们更好地构建自己的ui界面。

一、了解定位器

查阅帮助文档:
Row:
在这里插入图片描述

翻译一下:

Row是一种将其子项沿单行定位的类型。它可以作为一种方便的方法,在不使用锚的情况下水平定位一系列物品。
如果行中的某个项目不可见,或者宽度或高度为0,则该项目将不会布局,也不会在行中可见。此外,由于行会自动将其子项水平定位,因此行中的子项不应使用左、右锚点.horizontalCenter、fill或centerIn锚点设置其x位置或水平锚定自身。如果需要执行这些操作,请考虑在不使用行的情况下定位项目。
请注意,行中的项目可以使用附着定位器的属性来访问有关其在行中位置的更多信息。

Colunm和Row几乎完全一样,这里就略过了。
Grid:
在这里插入图片描述

网格是一种以网格形式定位其子项的类型。
网格创建了一个足够大的单元格网格,可以容纳其所有子项,并将这些项从左到右、从上到下放置在单元格中。每个项目都位于其单元格的左上角,位置为(0,0)。
网格默认为四列,并根据需要创建尽可能多的行以容纳其所有子项。可以通过设置行和列属性来限制行和列的数量。
如果网格中的某个项目不可见,或者宽度或高度为0,则该项目将不会被布局,也不会在列中可见。此外,由于网格会自动定位其子项,因此网格中的子项不应设置其x或y位置,也不应使用任何锚点属性锚定自身。

这里我们可以先得出一个结论,那就是:
使用了定位器(Positioners:Row,Column,Grid)时,应该确保组件没有使用锚定位和xy坐标定位,否则会造成冲突无法生效的问题

二、Grid的使用

Row,Column的使用在之前的学习中已经接触过,无非是用一个花括号把一些组件包含起来。但Grid因为要设置行列数,所以会有所不同。
我们新建工程QmlPositioners,然后将四个矩形塞给Grid:

    Grid{
        Rectangle{
            id: topLeftRectId
            width: 100
            height: width
            color: "magenta"
            Text {
                anchors.centerIn: parent
                text: "1"
                font.pointSize: 20
            }
        }

        Rectangle{
            id: topRightRectId
            width: 100
            height: width
            color: "yellowgreen"
            Text {
                anchors.centerIn: parent
                text: "2"
                font.pointSize: 20
            }
        }

        Rectangle{
            id: bottomLeftRectId
            width: 100
            height: width
            color: "dodgerblue"
            Text {
                anchors.centerIn: parent
                text: "3"
                font.pointSize: 20
            }
        }

        Rectangle{
            id: bottomRightRectId
            width: 100
            height: width
            color: "red"
            Text {
                anchors.centerIn: parent
                text: "4"
                font.pointSize: 20
            }
        }
    }

可以看到,Grid里放入了四个矩形,且矩形并没有设置任何锚定位。
此时观察现象,发现是直接一行排列的,并没有如我们所想的2x2布局。
在这里插入图片描述
我们往Grid里添加代码,指定行列数:

    Grid{
        rows: 2
        columns: 2
		// ...
    }

重新运行:
在这里插入图片描述
这次符合预期了。
我们修改第一个矩形的宽高,从100改为50:
在这里插入图片描述
我们可以发现,第一列的宽度取决于该列中最大的组件元素,而矩形1在它的区域内默认显示在左上角,并不会居中。
我们刚才是这样写的,但事实上有些冗余:

        rows: 2
        columns: 2

当我们添加第五个矩形,观察现象:
在这里插入图片描述
你会发现矩形5把矩形1给盖住了,原因是2x2的Grid布局对第五个矩形无效。
所以为了避免这种情况,最好使用rows或columns的其中一个来约束。
我们只设置columns: 2,观察现象:
在这里插入图片描述
可以看到,矩形5自动适应放到了第三行,因此这种方式会更加灵活。
另外,类似于anchors,定位器也可以设置组件间的间距:

spacing: 10

在这里插入图片描述
也可以单独控制rowSpacingcolumnSpacing:
在这里插入图片描述

我们还可以设置定位器周围的边距,即上下左右的边缘填充宽度,可以统一设置,也可以单独设置:

padding: 10
// leftPadding: 10
// rightPadding: 10
// topPadding: 10
// bottomPadding: 10

在这里插入图片描述
回到刚才第一个矩形默认放置在左上角的问题,我们可以对Grid设置对齐属性:

        horizontalItemAlignment: Grid.AlignHCenter
        verticalItemAlignment: Grid.AlignVCenter

在这里插入图片描述
可以看到矩形1按照我们希望的排列显示了。这种设置可以修改Grid中每一项默认的对齐策略,可以居中,也可以靠在右侧或底部,看你怎么想。
最后,还有一个有趣的设置:

LayoutMirroring.enabled: true

在这里插入图片描述
可以看到,这里按照从右到左,从上到下进行排列。LayoutMirroring可以帮你按照水平轴进行翻转,但如果想要翻转垂直轴就不行了,而且实现起来也比较复杂。

三、总结

本文中主要对Grid进行了学习和了解,虽然没有对Row,Column有太多介绍,但它们基本都和Grid类似。之前我们用anchor来进行九宫格的布局,可以看到当时需要对每一个组件进行单独的锚定位,实现起来非常繁琐,而如果使用本文中的Grid,则会简单很多。我们只需要设置简单的行列数,不需要给每一个组件元素设置布局策略,即可轻松实现想要的布局,这在实际项目开发中将十分发挥非常高效的作用。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐