使用锚点定位#

通过锚点属性放置项目

除了更传统的 网格 ,Qt Quick还提供了通过概念 锚点 布局项目的方式。每个项目可以被视为有一个由7条不可见的“锚线”组成的集合: 左边水平居中右边顶部垂直居中基线 , 和 底部

../_images/edges_qml.png

基线(图示中未显示)对应于文字所坐的假想线。对于没有文字的项目,它等同于 顶部

Qt Quick的锚点系统允许你定义不同项目锚线之间的关系。例如,你可以写出

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; ... }

在这种情况下, rect2 的左边边界绑定到 rect1 的右边边界,产生以下结果

../_images/edge1.png

你可以指定多个锚点。例如

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.top: rect1.bottom; ... }
../_images/edge3.png

通过指定多个水平和垂直锚点,你可以控制项目的大小。以下, 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; ... }
../_images/edge4.png

还有一些方便的锚点。 anchors.fill 是一个方便项,它等同于设置目标项的左边、右边、顶部和底部的左边、右边、顶部和底部的锚点。 anchors.centerIn 是另一个方便的锚点,类似于将目标项目的 verticalCenter 和 horizontalCenter 锚点设置为 verticalCenter 和 horizontalCenter。

锚点边距和偏移量#

锚点系统还允许为项目的锚点指定边距和偏移量。《边距》指定要在项目的外部留出的空空间量,而偏移量允许通过中心锚线来操作位置。项目可以通过 leftMarginrightMargintopMarginbottomMargin 单独指定其锚点边距,或者使用 anchors.margins 为所有四边指定相同的边距值。锚点偏移量使用 horizontalCenterOffsetverticalCenterOffsetbaselineOffset 指定。

../_images/margins_qml.png

以下示例指定了左边距

Rectangle { id: rect1; ... }
Rectangle { id: rect2; anchors.left: rect1.right; anchors.leftMargin: 5; ... }

在这种情况下,为rect2左侧预留了5像素的边距,产生以下效果

../_images/edge2.png

注意

锚定边距仅适用于锚点;它们不是应用于Item的通用边距应用方式。如果一个边指定了锚定边距,但该元素没有锚定到该边上的任何元素,则不应用边距。

更改锚点#

Qt Quick 为指定状态中的锚点提供了AnchorChanges类型。

AnchorChanges可以使用AnchorAnimation类型进行动画处理。

锚点还可以在 JavaScript 中强制更改。但是,这些更改应谨慎排序,否则可能会导致意外的结果。以下举例说明该问题

//bad code
Rectangle {
    width: 50
    anchors.left: parent.left

    function reanchorToRight() {
        anchors.right = parent.right
        anchors.left = undefined
    }
}
../_images/anchor_ordering_bad.png

当调用reanchorToRight时,函数首先设置右侧锚点。在那个时间点,左右两个锚点都设置了,元素将会水平拉伸以填充其父元素。当左侧锚点被移除后,新宽度将保持。因此,在 JavaScript 中更新锚点时,应首先移除不再需要任何锚点,然后设置所需的任何新锚点,如下所示

++—————————————–+ || .. 图像:: images/anchor_ordering.png| ++—————————————–+

因为绑定的评估顺序没有定义,不建议通过条件绑定更改锚点,因为这可能会导致上述排序问题。在以下示例中,矩形最终将扩展到其父元素的完整宽度,因为在绑定更新期间,左右两个锚点将同时设置。

//bad code
Rectangle {
    width: 50; height: 50
    anchors.left: state == "right" ? undefined : parent.left;
    anchors.right: state == "right" ? parent.right : undefined;
}

应该改为使用AnchorChanges进行重写,因为AnchorChanges会自动在内部处理排序问题。

限制#

出于性能考虑,您只能将元素锚定到其兄弟元素和直接父元素。例如,以下锚定无效,并将会产生警告

//bad code
Item {
    id: group1
    Rectangle { id: rect1; ... }
}
Item {
    id: group2
    Rectangle { id: rect2; anchors.left: rect1.right; ... }    // invalid anchor!
}

此外,基于锚定的布局不能与绝对定位混合。如果一个元素指定了其x位置并设置了anchors.left,或者设置了左边和右边的锚点但额外设置了width,结果不明确,因为不清楚元素应该使用锚定还是绝对定位。同样,当使用诸如 Row 和 Grid 之类的定位器时也适用,这些定位器可能设置了元素的xy属性。如果您希望从基于锚定的定位转换为绝对定位,可以通过将其设置为undefined来清除锚点值。