Qt Quick hates me
August 17, 2012
I haven’t blogged since a while, because I do not do much KDE hacking lately, but today I’ve got around to playing with QML again.
The goal was to build something like a breadcrumb navigation widget, where the current directory is indicated by its name being written in a larger font. Here’s what I arrived at after a few minutes:
import QtQuick 1.1 Rectangle { width: 800 height: 100 color: "black" Row { anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top spacing: 10 Repeater { id: repeater property int currentIndex: 4 model: ["/home", "/username", "/some", "/pseudo", "/path"] Text { text: modelData font.pixelSize: index == repeater.currentIndex ? 40 : 20 color: "white" } } } }
Close enough. Just adjust that alignment:
... Text { ... height: 60 verticalAlignment: Text.AlignBottom } ...
Gah! Can you see it? The baselines are misaligned. Usually, you lay out text such that all letters “sit” on an even line (the baseline).
The documentation does not mention any type baseline alignment in a Row element (or any type of vertical alignment in a Row element, for that matter).
I then tried to hack around this problem by dropping the Row element and laying out the Text elements manually, but the elements in the repeater won’t anchor to each other. That’s probably a problem with the elements not being fully initialized when the anchor property is evaluated, but at this point I give up.
This has been my second experience with Quick. When I tried it for the first time, my goal was a Quick version of the Planarity game. I got stuck when I noticed that Qt Quick 1 does not have any kind of line or ellipse primitive (only rectangles and images). Really?!?
So, while I understand very well and appreciate the idea behind Qt Quick, I have come to the conclusion that Qt Quick hates me. Or I have a talent of hitting a roadblock within ten minutes, regardless of the general direction.
P. S. Turns out the WordPress WYSIWYG editor hates me, too. (Well, either me or the combination of <pre> and images.)
August 17, 2012 at 21:06
Sure do the text’s baselines not align. The text fragments have a different font-size and you align there bottom and not the baseline.
You do not need to do everything with QML base components as shipped with Qt 4.8. Just look if there are other components which may do what you like to achieve or use QDeclarativeItem/QGraphicsItem to write yur own component(s). That enables full access to QFontMetrics and all of Qt. You could also go with tge easy way to just export a qreal fontBaseline(QString, QFont) and do the offser calc/positioning in QML.
August 17, 2012 at 23:16
Hi,
I know why that happens.Your printing the text in a loop meaning that each individual text is on it’s own.
If you where to print it like this:
Text {
id: name
text: “/home/username/some/pseudo/path”
color: “white”
}
then you do get the baseline you want. And yeah, then it gets a whole lot more complicated to do whatever you want to do since you can’t simply say “click path”.. How would you know where path is 😉
What you can do – which will make it a whole lot more complicated – is making a custom “fontdata” object from http://qt-project.org/doc/qt-4.8/qfontmetrics.html. Yes, just to get/calculate the base line!
Another thing you can do is report a bug (or feature request) in Qt to request a baseline property in the Text component.
Good luck!
August 18, 2012 at 00:07
The missing text baseline anchor is worth a bug report.
August 18, 2012 at 03:47
anchors.baseline
August 18, 2012 at 07:05
The alignment in the pictures doesn’t make any sense. It’s not baseline but it’s not bounding box either. In the AlignBottom case the big slash seems to be aligned with the small text baseline but not with the small slashes.
Look like a bug.
August 18, 2012 at 09:18
Ehm, you do know there is an anchors.baseline property right?
Giving the row item a proper height then adding “anchors.baseline: parent.verticalCenter;” to the Text item gives me precisely what you want.
August 18, 2012 at 14:51
I tested tested that out and it indeed works nicely!
import QtQuick 1.1
Rectangle {
width: 800
height: 100
color: “black”
Row {
anchors.horizontalCenter: parent.horizontalCenter
height: parent.height
Repeater {
id: repeater
property int currentIndex: 4
model: [“/home”, “/username”, “/some”, “/pseudo”, “/path”]
Text {
text: modelData
font.pointSize: index == repeater.currentIndex ? 40 : 20
color: “white”
anchors.baseline: parent.verticalCenter
}
}
}
}
Just posting the snippet for ease of use 🙂
August 18, 2012 at 21:49
Rectangle {
width: 800
height: 100
color: “black”
Row {
y:40
anchors.horizontalCenter: parent.horizontalCenter
spacing: 10
Repeater {
id: repeater
property int currentIndex: 4
model: [“/home”, “/username”, “/some”, “/pseudo”, “/path”]
Text {
text: modelData
font.pixelSize: index == repeater.currentIndex ? 40 : 20
color: “white”
anchors.baseline: parent.verticalCenter
}
}
}
}
August 19, 2012 at 18:05
Qt Quick hates everyone (who wants to do serious work in it). Wait until you want to bridge QML and C++, then the real hell will start…
A disappointed QML user (boy, am I happy that Digia is going to maintain and develop QtWidgets during the lifetime of Qt 5.x: http://blog.qt.nokia.com/2012/08/09/digia-extends-its-commitment-to-qt-with-plans-to-acquire-full-qt-software-technology-and-business-from-nokia/).