在 QML 代码中,我想在图像中放置一个包含大写单词的标签。 标签位于图像的底部,我希望文本的底部与图像的边缘匹配(例如,像日记中的方格纸)。通过使两者的底部与
匹配anchors.bottom: myImage.bottom
我无法避免字母和图像边缘之间有一些空格。
我将其简化为如下示例:
Rectangle {
id: content
width: 300
height: 300
color: "blue"
Label {
text: "ABC"
color: "black"
font.pixelSize: 200
anchors.bottom: content.bottom
anchors.horizontalCenter: content.horizontalCenter
background: Rectangle{
color: "green"
}
}
}
我可以看到字母和蓝色矩形底部之间有一个绿色空间。
除了弄乱
anchors.bottomMargin
的值之外,还有其他简单的方法可以解决此问题吗?
正如JarMan提到的,我发布我的评论作为答案,但添加了详细信息。
根据文档,每个可见的
Item
有四个垂直锚线:top
、verticalCenter
、baseline
和 bottom
。如果组件不是 Text
组件,则 baseline
与 top
锚点相同。 [1]
对于
Text
组件,假设标准字体和 Text
的初始大小,baseline
是文本所在的位置,其中包含“A”和“B”等字符,正好放置在 的顶部baseline
。基线如下图所示。
“空白空间”实际上是baseline
和
Text
项目底部之间的空间,可以用于锚定。如下代码所示:
Label {
anchors.baseline: parent.bottom
}
基线位置也可以从baselineOffset
此代码生成上面的图像。
Label {
id: label
text: 'AxyÁ'
font.family: 'Times New Roman'
font.pixelSize: 100
background: Rectangle { color: '#fed' }
Repeater {
model: ['top','baseline','verticalCenter','bottom']
Rectangle {
anchors.top: parent[modelData]
height: 1; width: parent.width; color: Qt.hsva(index/4,.5,.8)
Text {
color: parent.color; text: modelData; padding: 5;
anchors { left: parent.right; baseline: parent.top }
}
}
}
}
Text
的一些字形,例如“g”、“y”和“p”,其中部分字符延伸到基线以下。为了解决这个问题,我们可以使用
states
根据可能延伸到基线以下的字符来更改锚点。以下代码检查文本中是否存在
yqpjg
,如果找到任何这些字符,则会相应地调整锚点。
Rectangle {
color: '#fed'
Text {
id: label
text: 'ABC'
font.pixelSize: 100
anchors.horizontalCenter: parent.horizontalCenter
states: [
State { when: !label.text.match('[yqpjg]');
AnchorChanges { target: label; anchors.baseline: parent.bottom } },
State { when: label.text.match('[yqpjg]');
AnchorChanges { target: label; anchors.bottom: parent.bottom } }
]
//** Or just use the baselineOffset. **
// x: (parent.width - width)/2
// y: parent.height - (label.text.match('[yqpjg]') ? height : baselineOffset)
}
}
指标在 QML 中,我们可以使用
FontMetrics 访问这些值。
下图演示了Label
中的一些值。
此代码生成上面的图像。
Label {
id: label
text: 'AxyÁ'
font.family: 'Times New Roman'
font.pixelSize: 100
background: Rectangle { color: '#fed' }
FontMetrics { id: metrics; font: label.font }
Repeater {
model: [
['overlinePosition', label.baselineOffset - metrics.overlinePosition],
['\nascent', label.baselineOffset - metrics.ascent],
['baseline', label.baselineOffset],
['xHeight', label.baselineOffset - metrics.xHeight],
['strikeOutPosition', label.baselineOffset - metrics.strikeOutPosition],
['\nunderlinePosition', label.baselineOffset + metrics.underlinePosition],
['descent', metrics.descent + label.baselineOffset],
['\nheight', metrics.height],
]
Rectangle {
y: modelData[1] ?? 0
height: 0.5; width: parent.width; color: Qt.hsva(index/7,1,.7,1)
Text {
color: parent.color; text: modelData[0]; padding: 5;
anchors { left: parent.right; verticalCenter: parent.top }
}
}
}
}
ascent
略低于顶部位置。在此示例中,我使用了Times New Roman,其中下降与字形的高度相匹配,尽管下降有时可能高于
Text
的底部。总之,如果您需要简单的对齐,锚点就足够了。但是,为了对文本位置进行更高级的控制,您应该使用
FontMetrics
。