Solved Conditional alignment in a delegate based on text width?
-
I have a listview that works great, and when a name that is very long is displayed, it is clipped properly.
My problem is that if the text fits inside the width of the text control I would like it to be horizontally centered. If the text is too long and will be clipped, I want it aligned to the left so that you can read the start of the 'name' and the excessive portion is clipped only on the right.
Text { id: textName x: 18 y: 6 width: 392 height: 28 color: "#ffffff" text: "" font.bold: true font.pixelSize: 22 style: Text.Outline clip: true wrapMode: Text.NoWrap verticalAlignment: Text.AlignVCenter horizontalAlignment: ( text.paintedWidth > width ) ? Text.AlignLeft : Text.AlignHCenter }
This text declaration is inside of my delegate declaration like this:
delegate: Rectangle { ...some values Text { ...the text declaration shown above. } }
I was expecting the conditional I placed in the horizontalAlignment property to get evaluated at least everytime the value of Text.text changed. Unfortunately, it never evaluates as anything other than false (and therefore always horizontally centering the text.)
Event if I set the default value of text to some really long string, it acts as if text.paintedWidth is always less than the width.
If I force the evaluation to be 'true' I get left justified text, e.g.:
horizontalAlignment: ( true ) ? Text.AlignLeft : Text.AlignHCenter
Is there something I'm missing?
Thanks :)
-
I was misusing things... Here's how to do this (at least how I just found how to do this - I am interested in other solutions as well)
Text { id: textName x: 18 y: nTextStartingY width: 392 height: 28 color: "#ffffff" text: name font.bold: true font.pixelSize: 22 style: Text.Outline clip: true wrapMode: Text.NoWrap verticalAlignment: Text.AlignVCenter FontMetrics { id: textNameFontMetrics font: textName.font } horizontalAlignment: ( textNameFontMetrics.boundingRect( textName.text ).width >= textName.width ) ? Text.AlignLeft : Text.AlignHCenter }
Works nicely for me.
-
You can simply compare the text implicitWidth to its parent's width which serves as its holder.
Item { x: 18 y: nTextStartingY width: 392 height: 28 Text { anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter } horizontalAlignment: implicitWidth >= parent.width ? Text.AlignLeft : Text.AlignHCenter } }
Hope this helps.
-
I will give that a try, thanks! It would be much less brute force than my current solution.
-
@VRHans I just modified my answer because i noticed that you have a specific width set on the Text component. As you noticed, I created an Item which serves as the holder/container and anchored the Text to it.
-
Hi! You can also use
contentWidth
:horizontalAlignment: ( contentWidth > width ) ? Text.AlignLeft : Text.AlignHCenter
-
@Wieland - For some reason I can't mark your reply as the answer/solution, the option isn't available.
-
@VRHans Yes, the new forum (it's actually not that new anymore :)) doesn't support this. Voting good answer up with the thump up button is the way to go.