Qt Quick 笔记 - Anchors

看到许多 Qt Quick 样例中都会用到 Anchors,在官网这里找到了资料。还有这里也有详细的说明。

除了Grid, Row, and Column,Anchors 也可以用来布局。

注意只能对兄弟或父母 item 使用 anchors

Anchors 是 Item 中的属性,所以大多数类型都可以使用 Anchors。

一图胜千言:

![edges_qml][edges_qml]

简单的例子:

// ...
Rectangle { 
    id: rect1
    //... 
}

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

布局就会是这样子:

![edge1][edge1]

换一下

//...
Rectangle { 
    id: rect1
    //... 
}

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

布局就会是这样子

![edge3][edge3]

anchors.baseline 是一条假想的线,代表文本的位置。对于无文本的 item 它跟 top 一致。

还有一些比较方便的属性

anchors.fill: something 就是去填满 something,即 left,right,top, bottom 值都相等。

anchors.centerIn: something 就是中心与 something 相等,即 verticalCenter, horizontalCenter 值相等。

anchors.margins: 实数 以像素为单位设置间距,再次一图胜千言:

![margins_qml][margins_qml]

例子

//...
Rectangle { 
    id: rect1
    //... 
}

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

![edge2][edge2]

注意 margins 是按 anchors 来设置间距,假如没有设置 anchor,margins 就会失效。

此时可以用偏移值来设置间距,共三种:

  • anchors.horizontalCenterOffset : 实数

  • anchors.verticalCenterOffset : 实数

  • anchors.baselineOffset : 实数

使用 AnchorChanges 去处理状态

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

使用 AnchorAnimation 激活 AnchorChanges:

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

![anchor_ordering][anchor_ordering]

可以直接用 JavaScript 代替,但是要小心使用,会有很多坑

 //会出问题
Rectangle {
    width: 50
    anchors.left: parent.left

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

会变成这样:

![anchor_ordering_bad][anchor_ordering_bad]

要先释放不需要的属性再去更新其它属性

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 内部就会自动处理了。

最后说明,不要跟绝对坐标混用,要用绝对坐标时先把冲突的 anchor 设置为 undefined ​ [edges_qml]: /img/post/qt-quick-anchors/edgesqml.jpg [edge1]: /img/post/qt-quick-anchors/edge1.jpg [edge3]: /img/post/qt-quick-anchors/edge3.jpg [marginsqml]: /img/post/qt-quick-anchors/marginsqml.jpg [edge2]: /img/post/qt-quick-anchors/edge2.jpg [anchorordering]: /img/post/qt-quick-anchors/anchorordering.jpg [anchororderingbad]: /img/post/qt-quick-anchors/anchorordering_bad.jpg