Qml text wrap (max width)
Solution 1
You can almost do this neatly with states. The problem is that attempting to set the width of the parent by assigning it to the paintedWidth of the text box means it then sets the width of the text box, which QML detects as influencing paintedWidth. It wouldn't recurse further than this, but QML still kicks out warnings. One way around the problem is to do as follows, and have a dummy invisible text box that just works out how wide the text is/should be. Its a bit of a hack, but it works nicely.
You could change the "when" property of the state to be dependent on the size of the dummy text box (rather than the length of the string) if you preferred a pixel limit on the width of the box.
import QtQuick 1.0
Rectangle {
id: containing_rect
property string text
text: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
//text: "a short string"
Text {
id: text_field
anchors.top: parent.top
anchors.left: parent.left
height: parent.height
width: parent.width
text: parent.text
wrapMode: Text.WordWrap
}
Text {
id: dummy_text
text: parent.text
visible: false
}
states: [
State {
name: "wide text"
when: containing_rect.text.length > 20
PropertyChanges {
target: containing_rect
width: 200
height: text_field.paintedHeight
}
},
State {
name: "not wide text"
when: containing_rect.text.length <= 20
PropertyChanges {
target: containing_rect
width: dummy_text.paintedWidth
height: text_field.paintedHeight
}
}
]
}
Solution 2
Here's another way, which uses the Component.onCompleted script. It's more static than my other method, so I guess it depends on what you want to do with it.
import QtQuick 1.0
Rectangle {
id: containing_rect
property string text
height: text_field.paintedHeight
text: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat"
//text: "a short string"
Text {
id: text_field
anchors.top: parent.top
anchors.left: parent.left
height: parent.height
width: parent.width
text: parent.text
wrapMode: Text.WordWrap
}
Component.onCompleted: {
if (text_field.paintedWidth > 200) {
width = 200
} else {
width = text_field.paintedWidth
}
}
}
Solution 3
You can also try something like this, using the dummy text box mentioned above:
width: Math.min(dummy_text.paintedWidth, 250)
This will use the painted size of the text unless it is greater than your specified pixel width.
Solution 4
Try this:
Text {
property int MAX_WIDTH: 400
width: MAX_WIDTH
onTextChanged: width = Math.min(MAX_WIDTH, paintedWidth)
}
Solution 5
Very late to the party but the clean solution is to use an embedded TextMetrics object. Like this:
...
Text {
id: textObj
width: Math.min(textWidth, myThreshold)
// access to binding-loop-free width and height:
readonly property alias textWidth: textMetrics.boundingRect.width
readonly property alias textHeight: textMetrics.boundingRect.height
TextMetrics {
id: textMetrics
font: textObj.font
text: textObj.text
elide: textObj.elide
}
}
NicoMinsk
Avec plus de 15 ans d'expérience dans l'IT, je suis fier de travailler comme CTO chez Kang, où je dirige une équipe de six développeurs, créant des fonctionnalités uniques.🚀 Mon rôle de Leader est d'aider, de motiver, de faire progresser mon équipe pour accomplir de nouveau défi chaque Jour ! Si vous aussi, vous êtes Fan de Laravel & de PHP, n'hésitez pas à me contacter & pourquoi pas nous rejoindre !
Updated on July 09, 2022Comments
-
NicoMinsk almost 2 years
I would like to put text inside a bubble, and I want that my bubble be equal to the text width, but if the text length is too long, I would like the text to wrap automatically and be equal to the parent width.
This code works but the text is not wrapping if text is too long:
Rectangle { id:messageBoxCadre width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width+10 height: messageBox.height+5 color: modelData.myMessage ? "#aa84b2":"#380c47" radius: 10 Text { id:messageBox text: '<b><font color=purple>'+modelData.message+'</font></b> ' wrapMode: "WordWrap" } }
and I tried this, text wrap, but if the text is too small the bubble width is not equal to the text size:
Rectangle { id:messageBoxCadre width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width+10 height: messageBox.height+5 color: modelData.myMessage ? "#aa84b2":"#380c47" radius: 10 Text { id:messageBox width: (modelData.messageLength>25)? (wrapper.width - 20): messageBox.width text: '<b><font color=purple>'+modelData.message+'</font></b> ' wrapMode: "WordWrap" } }