除了更传统的 Grid、Row 和 Column 之外,Qt Quick 还提供了使用锚点概念来布局项目的方法。
每个项目都可以被认为有一组 7 条不可见的“锚线”:左、水平中心、右、顶部、垂直中心、基线(默认与顶部相同)和底部。
Qt Quick 锚定系统允许定义不同项目的锚线之间的关系。例如:
Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }
rect2 的左边缘绑定到 rect1 的右边缘:
可以指定多个锚点。例如:
Rectangle { id: rect1; ... }
Rectangle { id: rect2;
anchors.left: rect1.right;
anchors.top: rect1.bottom; ... }
通过指定多个水平或垂直锚点,可以控制项目的大小。下面,rect2 锚定在 rect1 的右侧和 rect3 的左侧。 如果移动任何一个蓝色矩形,rect2 将根据需要拉伸和收缩:
Rectangle { id: rect1; x: 0; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.right: rect3.left; ... }
Rectangle { id: rect3; x: 150; ... }
还有一些方便的锚点:
- anchors.fill:与设置目标项的左、右、上、下左、右、上、下锚点相同。
- anchors.centerIn:与将 verticalCenter 和 horizontalCenter 锚点设置为目标项的verticalCenter 和horizontalCenter 相同。
锚定边距和偏移量
锚定系统还允许为项目的锚定指定边距和偏移量。
边距:要离开项目锚点外部的空白空间量。
偏移量:允许使用中心锚线来操纵定位。
一个项目可以通过 leftMargin、rightMargin、topMargin 和 bottomMargin 单独指定其锚点边距,或者使用 anchors.margins 为所有四个边指定相同的边距值。使用 horizontalCenterOffset、verticalCenterOffset 和 baselineOffset 指定锚偏移。
以下示例指定左边距:
Rectangle { id: rect1; ... }
Rectangle { id: rect2;
anchors.left: rect1.right;
anchors.leftMargin: 5; ... }
rect2 左侧保留 5 个像素的边距:
改变锚
Qt Quick 提供了 AnchorChanges 类型来指定状态中的锚点。
State
{
name: "anchorRight"
AnchorChanges
{
target: rect2
anchors.right: parent.right
anchors.left: undefined //移除左锚点
}
}
可以使用 AnchorAnimation 类型对 AnchorChanges 进行动画处理。
Transition
{
AnchorAnimation {} //在相应的状态更改中为任何 AnchorChanges 设置动画
}
锚点也可以在 JavaScript 中强制更改。但是,这些更改应谨慎操作,否则可能会产生意想不到的结果。以下示例说明了该问题:
//糟糕的代码
Rectangle
{
width: 50
anchors.left: parent.left
function reanchorToRight()
{
anchors.right = parent.right
anchors.left = undefined
}
}
当调用 reanchorToRight() 时,该函数首先设置右锚点。 此时,左右锚点均已设置,项目将水平拉伸以填充其父项。 当左锚点未设置时,新宽度将保持不变。 因此,在 JavaScript 中更新锚点时,应该首先取消设置不再需要的任何锚点,然后才设置任何需要的新锚点,如下所示:
Rectangle
{
width: 50
anchors.left: parent.left
function reanchorToRight()
{
anchors.left = undefined
anchors.right = parent.right
}
}
限制
出于性能原因,只能将项目锚定到其兄弟姐妹和直接父项。
例如,以下锚点无效并会产生警告:
//糟糕的代码
Item
{
id: group1
Rectangle { id: rect1; ... }
}
Item
{
id: group2
Rectangle { id: rect2; anchors.left: rect1.right; ... } // 无效的锚
}
此外,基于锚的布局不能与绝对定位混合。如果一个项目指定了它的 x 位置并且还设置了 anchors.left,或者锚定了它的左右边缘但另外设置了一个宽度,结果是不确定的,因为项目应该使用锚定还是绝对定位并不清楚。对于使用 anchors.top 和 anchors.bottom 设置项目的 y 和高度,或者设置 anchors.fill 以及宽度或高度,也同样如此。这也适用于使用定位器(例如 Row 和 Grid)时,它们可以设置项目的 x 和 y 属性。如果希望从使用基于锚的定位更改为绝对定位,可以通过将锚值设置为 undefined 来清除锚值。