QML学习(六) anchors锚点和坐标,以及anchors锚点的使用
先来看看上一篇文章中的代码和效果
上一篇中讲到,第一个QML程序虽然做出来了,但程序界面里边元素的显示位置跟预想的不一样,这其实就是整体上对QML中的坐标使用存在问题。
改成这样,全以锚点来控制各个元素的坐标
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12Window {visible: truewidth: 400height: 200//改掉标题title: qsTr("测试程序")//添加个矩形Rectangle {id: rectanglewidth: 180height: 80color: "red"border.color: "blue"anchors.top: parent.topanchors.rightMargin: 10}//再添加个矩形Rectangle {id: rectangle2width: 180height: 80color: "red"border.color: "blue"anchors.top: parent.topanchors.left: rectangle.right+20anchors.right: parent.right}//添加一行文字Text {id: myTextwidth: 200height: 40text: "Hello, QML!"font.pointSize: 26anchors.top: rectangle.bottom}Button{id: myButtontext: "Click Me"anchors.top: myText.bottomanchors.bottom: parent.bottomanchors.topMargin: 20onClicked: {console.log("Button clicked!");}}
}
效果就会变成这样:
整个Window里边,按照从上到下,从左到右,依次加入两个方框,一串文字,一个按钮,全部使用anchors锚点。
今天这篇主要介绍QML中元素的坐标,以及anchors瞄点的使用。
先来说一下QML中的坐标系统。
QML中的坐标系统通常是一个基于屏幕像素的二维笛卡尔坐标系。坐标系的原点(0,0)通常位于界面的左上角,X轴向右延伸,Y轴向下延伸。每个QML元素(如Rectangle、Image等)都有自己的局部坐标系,该坐标系以元素的左上角为原点。
Rectangle {width: 100height: 100x: 50 // 从父元素的左边缘向右移动50个像素y: 50 // 从父元素的上边缘向下移动50个像素color: "blue"
}
像上面例子里这种,就是给元素的x,y赋值来决定该元素在父元素中的坐标位置(注意:是他所在父元素中的坐标位置,也就是相对坐标,不是整个屏幕的绝对位置,这里要理解清楚绝对坐标和相对坐标)。这种全程以坐标来控制元素的位置肯定也可以,但这样写的话,遇到元素比较多,界面比较复杂的情况就很头疼,这时候大家就会引入anchors瞄点的应用,并结合一些布局,来完成整页界面的设计分布。
接下来说一下anchors瞄点的使用,来控制元素的位置。先来看一个示例:
import QtQuick 2.0Rectangle {width: 200;height: 200;color: "red"Rectangle {width: 100;height: 100;color: "blue"// 使用 anchors 锚点将蓝色矩形的左边与父矩形的左边对齐anchors.left: parent.left;// 将蓝色矩形的顶部与父矩形的顶部对齐anchors.top: parent.top;// 为蓝色矩形的左边添加一个偏移量 20 像素anchors.leftMargin: 20;// 为蓝色矩形的顶部添加一个偏移量 20 像素anchors.topMargin: 20;}
}
在这个 QML 示例中,我们有一个父 Rectangle 和一个子 Rectangle。
对于子矩形(蓝色),我们使用 anchors.left: parent.left 将其左边与父矩形的左边对齐。这意味着子矩形的左边缘将与父矩形的左边缘在同一垂直位置。
类似地,使用 anchors.top: parent.top 将子矩形的顶部与父矩形的顶部对齐,使子矩形的上边缘与父矩形的上边缘在同一水平位置。
anchors.leftMargin: 20 为子矩形的左边添加了一个 20 像素的偏移量。这会将子矩形从父矩形的左边缘向右移动 20 像素。
anchors.topMargin: 20 为子矩形的顶部添加了一个 20 像素的偏移量,将子矩形从父矩形的上边缘向下移动 20 像素。
以下是另一个更复杂的示例,展示了多个锚点的使用:
import QtQuick 2.0Rectangle {width: 300;height: 300;color: "yellow"Rectangle {width: 150;height: 150;color: "green"// 将绿色矩形的右边与父矩形的右边对齐anchors.right: parent.right;// 将绿色矩形的底部与父矩形的底部对齐anchors.bottom: parent.bottom;// 右边偏移量为 30 像素anchors.rightMargin: 30;// 底部偏移量为 30 像素anchors.bottomMargin: 30;// 水平居中对齐,与父矩形的水平中心对齐anchors.horizontalCenter: parent.horizontalCenter;// 垂直居中对齐,与父矩形的垂直中心对齐anchors.verticalCenter: parent.verticalCenter;}
}
代码解释:
对于这个示例中的子矩形(绿色):
anchors.right: parent.right 使子矩形的右边缘与父矩形的右边缘对齐。
anchors.bottom: parent.bottom 使子矩形的底部与父矩形的底部对齐。
anchors.rightMargin: 30 会将子矩形从父矩形的右边缘向左偏移 30 像素。
anchors.bottomMargin: 30 会将子矩形从父矩形的底部向上偏移 30 像素。
anchors.horizontalCenter: parent.horizontalCenter 使子矩形的水平中心与父矩形的水平中心对齐,保证在水平方向上处于中心位置(考虑了之前的偏移)。
anchors.verticalCenter: parent.verticalCenter 使子矩形的垂直中心与父矩形的垂直中心对齐,保证在垂直方向上处于中心位置(考虑了之前的偏移)。
通过使用 anchors,可以方便地将一个元素相对于另一个元素进行定位,而不需要使用 x 和 y 坐标,这样可以让布局更加灵活和动态,尤其在处理不同屏幕尺寸和分辨率时。例如,在用户调整窗口大小时,使用锚点定位的元素会根据其锚定的父元素或其他元素自动调整位置,而使用 x 和 y 坐标定位的元素可能不会自动调整,除非手动编写代码来处理。
anchors 还支持更多的属性,例如:
anchors.fill:可以让子元素填充父元素的全部空间。
anchors.before 和 anchors.after:可以根据元素在布局中的前后顺序进行定位。
anchors.centerIn:可以将元素居中在另一个元素内。
现在总结一下:
在 QML 中,anchors(锚点)是一种强大的布局机制,它允许你将一个元素的边界与另一个元素的边界关联起来,从而实现灵活和动态的布局。以下是 anchors 的主要属性:
1、基本锚点属性:
anchors.left:将元素的左边界与另一个元素的左边界连接。
anchors.right:将元素的右边界与另一个元素的右边界连接。
anchors.top:将元素的上边界与另一个元素的上边界连接。
anchors.bottom:将元素的下边界与另一个元素的下边界连接。
2、偏移属性:
anchors.leftMargin:元素左边界相对于其锚定元素左边界的偏移量。
anchors.rightMargin:元素右边界相对于其锚定元素右边界的偏移量。
anchors.topMargin:元素上边界相对于其锚定元素上边界的偏移量。
anchors.bottomMargin:元素下边界相对于其锚定元素下边界的偏移量。
3、中心锚点属性:
anchors.horizontalCenter:将元素的水平中心与另一个元素的水平中心连接。
anchors.verticalCenter:将元素的垂直中心与另一个元素的垂直中心连接。
anchors.centerIn:将元素的中心置于另一个元素的中心。
4、填充属性:
anchors.fill:使一个元素填充另一个元素,即元素将占据其锚定元素的全部空间。
5、相对位置属性:
anchors.baseline:将元素的基线与另一个元素的基线连接,通常用于文本元素,将当前元素的基线与另一个元素的基线绑定,确保文本元素在垂直方向上按照文本基线对齐
估计大家也发现了,有时候你设置了一些元素的宽高但并没有生效,这种情况往往就是一些坐标位置,锚点控制,布局管理中,出现了优先级冲突。下来说下anchors锚点的优先级:
一、显式指定的优先级高于隐式布局规则:
当你使用 anchors 属性明确指定了元素的位置和尺寸约束时,这些明确的约束通常会优先于其他隐式的布局规则。例如,如果你同时使用 anchors.left 和 anchors.right 来确定元素的宽度,它将优先于元素的 width 属性或 implicitWidth。
二、多个锚点之间的优先级:
一般情况下,当设置多个锚点时,它们的优先级通常是根据它们的设置顺序和具体情况而定,但遵循一些基本的原则:
1.水平方向的优先级:在水平方向上,如果同时设置了 anchors.left 和 anchors.right 以及 width,通常 anchors.left 和 anchors.right 的组合将优先,因为它们更明确地定义了元素的水平范围;
2.垂直方向的优先级:对于垂直方向,如果同时设置了 anchors.top 和 anchors.bottom 以及 height,anchors.top 和 anchors.bottom 的组合会优先;
Rectangle {width: 100; height: 100; color: "red"Rectangle {// 蓝色矩形的高度将由 top 和 bottom 锚点决定anchors.top: parent.topanchors.bottom: parent.bottomcolor: "blue"}
}
蓝色矩形的高度将由 anchors.top 和 anchors.bottom 确定,会拉伸以填满父元素的上下边界,而不是使用 height 设定的尺寸。
3.中心锚点与边界锚点的优先级:当同时使用中心锚点(anchors.horizontalCenter 和 anchors.verticalCenter)和边界锚点时,一般来说,边界锚点会更优先,因为它们提供了更明确的位置信息;
4.填充属性的优先级:anchors.fill 是一个非常强大的属性,当设置了 anchors.fill 时,它通常会优先于其他锚点设置,因为它的目的是使元素填充另一个元素的全部空间;
5.边距属性的优先级:边距属性(anchors.leftMargin、anchors.rightMargin 等)会在相应的锚点属性之后起作用,用于调整元素与锚定元素之间的距离。它们不会改变锚点所确定的元素位置的基本关系,只是在已有的位置关系上添加偏移,相当于叠加了两个设置的属性;
Rectangle {width: 100; height: 100; color: "red"Rectangle {// 蓝色矩形根据 left 锚点定位,并添加左偏移anchors.left: parent.leftanchors.leftMargin: 20color: "blue"}
}
如上例子中,anchors.leftMargin 在 anchors.left 确定的位置基础上,将蓝色矩形向左偏移 20 像素。