如何在 QML 中将一些文本包裹在一个矩形中?
How to wrap some text in a rectangle in QML?
我必须执行一个非常简单的任务:我想在一个矩形内显示一段文本,并且该矩形的大小应该恰好是文本的宽度。
在 C++ 中,这很容易做到。只需定义 QString 并应用 QFontMetrics 来获取其宽度。然后定义具有该尺寸的矩形图形元素。它在五分钟内完成。
听说QML比较好用。因此,我期望在不到五分钟的时间内解决该问题。我没有,我仍然坚持下去。这是我尝试过的:
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
由于我不明白的某些原因,这不起作用。我找到了一种不完全适合我需要的方法:
Rectangle {
width: 100
height: 100
MouseArea {
id: myMouseArea
anchors.fill: parent
onClicked: parent.width=myText.contentWidth
hoverEnabled: true
}
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
在这种情况下,当我单击矩形时,它会获得正确的宽度。不过,我对这个解决方案不感兴趣,因为我不想通过单击来获得正确大小的矩形。
我希望每当 myText
更改文本时矩形的大小都得到正确的大小。在文本项中使用 onTextChanged
也不起作用。
我在这里错过了什么?
据我所知,在 Qt 5.4 中开发人员可以使用字体指标,因此在 QML 中它们相对较新。你得到的主要是 FontMetrics
and TextMetrics
。一个简单的用法示例:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
width: 280; height: 150
TextMetrics {
id: textMetrics
font.family: "Arial"
font.pixelSize: 50
text: "Hello World"
}
Rectangle {
width: textMetrics.width
height: textMetrics.height
color: "steelblue"
Text {
text: textMetrics.text
font: textMetrics.font
}
}
}
正如 Phrogz
在下面的评论中指出的那样,TextMetrics
类型不 支持测量换行文本。
编辑
对于有价值的东西,我从来没有需要在 QML 中使用指标。对我来说 content*
或 painted*
属性达到了目的,并且从 Qt 5.12 开始,它们似乎工作正常。又名以下两个解决方案生成正确的视觉行为:
// solution 1
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
// solution 2
Rectangle {
width: myText.paintedWidth
height: myText.paintedHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
对于像 OP 提出的这样一个简单的用例,我更喜欢这些解决方案而不是指标的使用。对于相反的情况 - 以特定大小调整文本 - 属性的组合可以达到目的,例如:
Rectangle {
anchors.centerIn: parent
width: 200
height: 30
Text {
anchors.fill: parent
text: "Wonderful Text"
minimumPixelSize: 2
fontSizeMode: Text.Fit
font.pixelSize: 200
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
这里的像素大小只是超过了顶部,但文本仍然适合,因为设置了 2
的最小尺寸,并且文本具有明确的适合策略和清晰的边界,由锚定定义。
我确定 Label 组件可以完成这项工作:
import QtQuick 2.1
import QtQuick.Controls 2.4
ApplicationWindow {
visible: true
Column {
Repeater {
model: [
{"color": "red", "radius": 1},
{"color": "green", "radius": 2},
{"color": "blue", "radius": 3}
]
Label {
padding: 0
text: modelData.color
font.family: "Helvetica"
font.pointSize: 50
background: Rectangle {
color: modelData.color
radius: modelData.radius
}
}
}
}
}
您不需要对文本项使用 anchors.fill: parent
,因为文本父项的大小取决于文本本身的大小。这是导致绑定循环。
这一定没问题。
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
我必须执行一个非常简单的任务:我想在一个矩形内显示一段文本,并且该矩形的大小应该恰好是文本的宽度。
在 C++ 中,这很容易做到。只需定义 QString 并应用 QFontMetrics 来获取其宽度。然后定义具有该尺寸的矩形图形元素。它在五分钟内完成。
听说QML比较好用。因此,我期望在不到五分钟的时间内解决该问题。我没有,我仍然坚持下去。这是我尝试过的:
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
由于我不明白的某些原因,这不起作用。我找到了一种不完全适合我需要的方法:
Rectangle {
width: 100
height: 100
MouseArea {
id: myMouseArea
anchors.fill: parent
onClicked: parent.width=myText.contentWidth
hoverEnabled: true
}
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
在这种情况下,当我单击矩形时,它会获得正确的宽度。不过,我对这个解决方案不感兴趣,因为我不想通过单击来获得正确大小的矩形。
我希望每当 myText
更改文本时矩形的大小都得到正确的大小。在文本项中使用 onTextChanged
也不起作用。
我在这里错过了什么?
据我所知,在 Qt 5.4 中开发人员可以使用字体指标,因此在 QML 中它们相对较新。你得到的主要是 FontMetrics
and TextMetrics
。一个简单的用法示例:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
width: 280; height: 150
TextMetrics {
id: textMetrics
font.family: "Arial"
font.pixelSize: 50
text: "Hello World"
}
Rectangle {
width: textMetrics.width
height: textMetrics.height
color: "steelblue"
Text {
text: textMetrics.text
font: textMetrics.font
}
}
}
正如 Phrogz
在下面的评论中指出的那样,TextMetrics
类型不 支持测量换行文本。
编辑
对于有价值的东西,我从来没有需要在 QML 中使用指标。对我来说 content*
或 painted*
属性达到了目的,并且从 Qt 5.12 开始,它们似乎工作正常。又名以下两个解决方案生成正确的视觉行为:
// solution 1
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
// solution 2
Rectangle {
width: myText.paintedWidth
height: myText.paintedHeight
Text {
anchors.fill:parent
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}
对于像 OP 提出的这样一个简单的用例,我更喜欢这些解决方案而不是指标的使用。对于相反的情况 - 以特定大小调整文本 - 属性的组合可以达到目的,例如:
Rectangle {
anchors.centerIn: parent
width: 200
height: 30
Text {
anchors.fill: parent
text: "Wonderful Text"
minimumPixelSize: 2
fontSizeMode: Text.Fit
font.pixelSize: 200
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
这里的像素大小只是超过了顶部,但文本仍然适合,因为设置了 2
的最小尺寸,并且文本具有明确的适合策略和清晰的边界,由锚定定义。
我确定 Label 组件可以完成这项工作:
import QtQuick 2.1
import QtQuick.Controls 2.4
ApplicationWindow {
visible: true
Column {
Repeater {
model: [
{"color": "red", "radius": 1},
{"color": "green", "radius": 2},
{"color": "blue", "radius": 3}
]
Label {
padding: 0
text: modelData.color
font.family: "Helvetica"
font.pointSize: 50
background: Rectangle {
color: modelData.color
radius: modelData.radius
}
}
}
}
}
您不需要对文本项使用 anchors.fill: parent
,因为文本父项的大小取决于文本本身的大小。这是导致绑定循环。
这一定没问题。
Rectangle {
width: myText.contentWidth
height: myText.contentHeight
Text {
id: myText
font.family: "Helvetica"
font.pointSize: 50
text: qsTr("The string I want to display")
}
}