PDA

View Full Version : Dynamically resize text



antialias_forum
12th January 2011, 16:00
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}
}
}


test.qml


import Qt 4.7
Item {
width: 50
height: 50
TextButton {
anchors.centerIn: parent
width: parent.width / 2
height: parent.height /2 }
}


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

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}



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?

markc
15th January 2011, 18:52
Just a quick simple suggestion, perhaps try fiddling with font.pixelSize instead.


property int fontSize: Math.round(textButton.height / 4)
...
font.pixelSize: (invisibleText.paintedWidth > parent.width) ? (parent.width / invisibleText.paintedWidth) * fontSize : fontSize

antialias_forum
18th January 2011, 09:34
That works, too. I have not found any difference in the behavior of font.pixelsize and font.pointsize in this case.
However, I was hoping to get rid of the 'invisible text'-hack somehow.

markc
19th January 2011, 08:31
I found that using pixelSize avoided this problem...


the text sometimes jumps in size and can, under specific circumstances, still exceed the rectangle length

rectalogic
7th May 2011, 00:37
However, I was hoping to get rid of the 'invisible text'-hack somehow.

You could scale the Text based on how much it exceeds your width at the specified pixelSize:


import Qt 4.7
Rectangle {
width: 200
height: 200
Text {
width: 200
height: 100
text: "Some sample text here"
font.pixelSize: height / 4
scale: paintedWidth > width ? (width / paintedWidth) : 1
transformOrigin: Item.TopLeft
}
}