I would like to achieve the following behavior for a text within a rectangle:
1) text fontSize to dynamically resize with the rectangle
2) text height should be 1/4 the height of the rectangle
3) if the text length is longer than the rectangle width then the text fontSize should be dynamically made smaller to ensure a fit
3) Has been giving me a hard time. I have a solution (see below) but it's a terrible hack. I use an invisible Text to check whether the width of the text string fits - and if it doesn't fit then rescale the text.
TextButton.qml
import Qt 4.7
Item {
id: textButton
width: 50
height: 50
property string someText : "some long text"
Rectangle {
id: rect
color: "purple"
anchors.fill: parent
Text {
id: invisibleText
anchors.centerIn: parent
text: someText
font.pointSize: textButton.height * 0.25
visible: false }
Text {
id: rectText
anchors.centerIn: parent
text: someText
font.pointSize: (invisibleText.paintedWidth > rect.width) ? 0.1+0.9 * parent.height * 0.25 * parent.width / invisibleText.paintedWidth : 0.1+0.9 * parent.height * 0.25}
}
}
import Qt 4.7
Item {
id: textButton
width: 50
height: 50
property string someText : "some long text"
Rectangle {
id: rect
color: "purple"
anchors.fill: parent
Text {
id: invisibleText
anchors.centerIn: parent
text: someText
font.pointSize: textButton.height * 0.25
visible: false }
Text {
id: rectText
anchors.centerIn: parent
text: someText
font.pointSize: (invisibleText.paintedWidth > rect.width) ? 0.1+0.9 * parent.height * 0.25 * parent.width / invisibleText.paintedWidth : 0.1+0.9 * parent.height * 0.25}
}
}
To copy to clipboard, switch view to plain text mode
test.qml
import Qt 4.7
Item {
width: 50
height: 50
TextButton {
anchors.centerIn: parent
width: parent.width / 2
height: parent.height /2 }
}
import Qt 4.7
Item {
width: 50
height: 50
TextButton {
anchors.centerIn: parent
width: parent.width / 2
height: parent.height /2 }
}
To copy to clipboard, switch view to plain text mode
Alternatively I tried the following:
a) bind the rectText.pointSize to the formula
font.pointSize: (paintedWidth > rect.width) ? 0.1+0.9 * parent.height * 0.25 * parent.width / paintedWidth : 0.1+0.9 * parent.height * 0.25
font.pointSize: (paintedWidth > rect.width) ? 0.1+0.9 * parent.height * 0.25 * parent.width / paintedWidth : 0.1+0.9 * parent.height * 0.25
To copy to clipboard, switch view to plain text mode
b) use a state change on the scale property of the rect and use a PropertyChanges Element
c) use the onHeightChanged and onWidthChanged signals to call a function which recalculates the font size
onHeightChanged: changeSize()
onWidthChanged: changesize()
...
function changeSize(){
rectText.font.pointSize = (rectText.paintedWidth > rect.width) ? 0.1+0.9 * textButton.height * 0.25 * textButton.width / rectText.paintedWidth : 0.1+0.9 * textButton.height * 0.25}
onHeightChanged: changeSize()
onWidthChanged: changesize()
...
function changeSize(){
rectText.font.pointSize = (rectText.paintedWidth > rect.width) ? 0.1+0.9 * textButton.height * 0.25 * textButton.width / rectText.paintedWidth : 0.1+0.9 * textButton.height * 0.25}
To copy to clipboard, switch view to plain text mode
All of these work...sort of but:
a) gives binding loop warnings
b) and c) lead to behavior where the text sometimes jumps in size and can, under specific circumstances, still exceed the rectangle length
Any ideas how to do this more cleanly?
Bookmarks