本页内容

使用锚点进行定位

除了较为传统的Grid 、Row 和Column 之外,Qt Quick 还提供了一种基于锚点概念的元素布局方式。可以将每个元素视为拥有7条不可见的“锚线”:left 、horizontalCenter 、right 、top 、verticalCenter 、baseline 和bottom 。

显示六条锚定线的矩形:左、右、上、下及中心线

基线(上图未显示)对应文本所在的假想线。对于没有文本的项目,它与“top”属性相同。

Qt Quick 锚定系统允许您定义不同项目锚线之间的关系。例如,您可以这样写:

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

在此情况下,rect2的左边缘与rect1 的右边缘绑定,效果如下:

rect1 和 rect2 并排显示,左边缘锚定在右侧

您可以指定多个锚点。例如:

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

rect2 位于 rect1 的下方和右侧

通过指定多个水平或垂直锚点,您可以控制元素的大小。下图中,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; ... }

rect2 位于左侧的 rect1 和右侧的 rect3 之间

此外还有一些便捷锚点。`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 像素的边距,效果如下:

rect1 和 rect2 并排显示,两者之间留有边距间隙

注意:锚点 边距仅适用于锚点;它们并非为 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 中通过命令式方式进行更改。但是,这些更改应按正确顺序进行,否则可能会产生意想不到的结果。以下示例说明了这个问题:

// May produce unexpected results
Rectangle {
    width: 50
    anchors.left: parent.left

    function reanchorToRight() {
        anchors.right = parent.right
        anchors.left = undefined
    }
}

三个步骤,展示了rect1在重新锚定时出现意外拉伸的情况

调用 `reanchorToRight ` 时,该函数首先设置右锚点。此时,左右锚点均已设置,项目将水平拉伸以填满其父容器。 当左锚点被清除时,新的宽度将保持不变。因此,在 JavaScript 中更新锚点时,应先清除不再需要的锚点,然后再设置所需的新锚点,如下所示:

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

    function reanchorToRight() {
        anchors.left = undefined
        anchors.right = parent.right
    }
}

三个步骤,展示rect1如何正确地从左锚点移动到右锚点

由于绑定表达式的求值顺序未被定义,不建议通过条件绑定来更改锚点,因为这可能会导致上述顺序问题。在下面的示例中,Rectangle 最终会扩展到其父容器全宽,因为在绑定更新期间,左锚点和右锚点会被同时设置。

// May produce unexpected results
Rectangle {
    width: 50; height: 50
    anchors.left: state == "right" ? undefined : parent.left;
    anchors.right: state == "right" ? parent.right : undefined;
}

应将其重写为使用 `AnchorChanges `,因为 `AnchorChanges ` 会在内部自动处理排序问题。以下是正确重写上述示例的方法:

// Correct code
Rectangle {
    id: rect
    width: 50; height: 50
    anchors.left: parent.left  // initial position

    states: State {
        name: "rightAligned"
        AnchorChanges {
            target: rect
            anchors.left: undefined
            anchors.right: parent.right
        }
    }
    function toggleAnchoring() {
        parent.state = (parent.state == "" ? "rightAligned" : "")
    }
}

限制

出于性能考虑,您只能将项目锚定到其兄弟节点和直接父节点。例如,以下锚定设置无效,并将引发警告:

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

此外,基于锚点的布局不能与绝对定位混合使用。如果一个项目既指定了x 位置又设置了anchors.left ,或者锚定了其左右边缘但同时设置了width ,则结果未定义,因为无法确定该项目应使用锚定还是绝对定位。 同样的情况也适用于同时设置项目的y 和height 属性,同时指定anchors.top 和anchors.bottom 属性,或者同时设置anchors.fill 以及width 或height 属性。当使用 Row 和 Grid 等定位器时,情况也是如此,这些定位器可能会设置项目的x 和y 属性。若希望从基于锚点的定位切换为绝对定位,可通过将锚点值设置为undefined 来清除该值。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.