Reputation: 43
I have QML Text elements in a ColumnLayout like so:
import QtQuick 2.0
import QtQuick.Layouts 1.1
Item {
Rectangle {
ColumnLayout {
anchors.fill: parent
anchors.bottomMargin: 5
Canvas {
Layout.fillHeight: true
Layout.fillWidth: true
}
Text {}
Text {}
Text {}
}
}
}
The canvas fill the top part of the column nicely and the Texts line up beneath it just fine. That anchors.bottomMargin sets a small margin only at the very bottom. But no matter what margins or anchors I set for the Texts, there is a lot of vertical empty space between them. The text is just numbers so there is no concern about characters that need to take up more room. How do I get rid of this space?
Upvotes: 4
Views: 4812
Reputation: 24406
I've run into this issue as well, and there wasn't a solution. However, in Qt 5.4, the FontMetrics and TextMetrics QML types were added.
FontMetrics has a comprehensive API which mirrors the C++ QFontMetricsF class, with some of it being imperative (functions). TextMetrics takes the functions in FontMetrics and makes them declarative (properties) for convenience, plus some extra properties for completeness.
Given some text string, TextMetrics will provide you with the tightBoundingRect
property, which, as its name suggests, is a tight bounding rectangle around the string, without the extra space that you normally see. Take that height from the height of a string with only numbers in it, and you get the superfluous height than can be used as negative spacing:
import QtQuick 2.4
Item {
Rectangle {
anchors.fill: parent
TextMetrics {
id: metrics
text: "1"
}
Column {
anchors.fill: parent
anchors.bottomMargin: 5
spacing: -(metrics.height - metrics.tightBoundingRect.height)
Text { text: "123" }
Text { text: "123" }
Text { text: "123" }
}
}
}
Note the warning from the documentation:
Warning: Calling this method is very slow on Windows.
That shouldn't be a problem if you only set the text/font on the TextMetrics object once though, as it will only calculate it once.
An alternative, but sketchy approach is to basically guess a value for the lineHeight
property of each Text
item.
import QtQuick 2.0
Item {
Rectangle {
anchors.fill: parent
Column {
anchors.fill: parent
anchors.bottomMargin: 5
Text { text: "123"; lineHeight: 0.8 }
Text { text: "123"; lineHeight: 0.8 }
Text { text: "123"; lineHeight: 0.8 }
}
}
}
As Shubhanga said, negative spacing will also work, but it's also not so great:
import QtQuick 2.0
Item {
Rectangle {
anchors.fill: parent
Column {
anchors.fill: parent
anchors.bottomMargin: 5
spacing: -4
Text { text: "123" }
Text { text: "123" }
Text { text: "123" }
}
}
}
Again, mentioned by Shubhanga, setting the text's height explicitly will work, but there's still guesswork involved. Like the two solutions above, you'll have to change the value you subtract from the height each time you change font size, and it won't scale between devices (low DPI desktop PC vs high DPI mobile):
import QtQuick 2.0
Item {
readonly property int heightAdjustment: 5
Rectangle {
anchors.fill: parent
Column {
anchors.fill: parent
anchors.bottomMargin: 5
Text {
text: "123";
height: implicitHeight - heightAdjustment
}
Text {
text: "123";
height: implicitHeight - heightAdjustment
}
Text {
text: "123";
height: implicitHeight - heightAdjustment
}
}
}
}
Upvotes: 4
Reputation: 1330
Have you tried using spacing
property? This is used to set spacing between layout's contents. The default value is 5. Try setting it as 0.
Reference ColumnLayout spacing property
Upvotes: 2