使用锚点定位#
通过锚点属性放置项目
除了更传统的 网格 , 行 或 列 ,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像素的边距,产生以下效果
注意
锚定边距仅适用于锚点;它们不是应用于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 } }
当调用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 之类的定位器时也适用,这些定位器可能设置了元素的x和y属性。如果您希望从基于锚定的定位转换为绝对定位,可以通过将其设置为undefined
来清除锚点值。