使用锚点定位

除了更传统的网格之外,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是另一个便利的锚点,它与将垂直居中和水平居中锚点设置为目标的垂直居中和水平居中相同。

锚点边距和偏移

锚定系统还允许为项的锚点指定边距偏移。边距指定项锚线外部留出多少空白空间,而偏移允许使用中心锚线来操纵定位。项可以通过leftMarginrightMargintopMarginbottomMargin分别指定其锚点的边距,或通过anchors.margins指定所有四个边的相同边距值。使用horizontalCenterOffsetverticalCenterOffsetbaselineOffset指定锚点偏移。

下面的示例指定一个左边距

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

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

注意:锚定边距只应用于锚定元素;它们不是将边距应用于Item的通用方法。如果为边指定了锚定边距,但是项目没有锚定在该边的任意元素,则不应用该边距。

更改锚点

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

State {
    name: "anchorRight"
    AnchorChanges {
        target: rect2
        anchors.right: parent.right
        anchors.left: undefined  //remove the left anchor
    }
}

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

Transition {
    AnchorAnimation {}  //animates any AnchorChanges in the corresponding state change
}

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

//bad code
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
    }
}

由于引用的评估顺序未定义,不建议通过条件引用更改锚点,因为这可能导致上述排序问题。在以下示例中,矩形最终将扩展到其父元素的全部宽度,因为在绑定更新期间同时设置左侧和右侧锚点。

//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,结果是不确定的,因为不清楚项目是应该使用锚定还是绝对定位。同样适用于设置项目的yheight以及anchors.topanchors.bottom,或者同时设置anchors.fill以及widthheight。当使用行和网格等位置器时,这同样适用,这些位置器可能会设置项目的xy属性。如果您想从基于锚定切换到绝对定位,可以通过将其设置为undefined来清除锚点值。

© 2024 Qt 公司有限公司。此处包含的文档贡献版权属于各自的所有者。此处提供的文档是根据自由软件基金会发布的GNU自由文档许可证版本1.3的条款许可的。Qt 和相关徽标是芬兰及其它国家/地区的 Qt 公司有限公司的商标。所有其他商标均为各自所有者的财产。