John Q. Workaday
John Q. Workaday

Reputation: 43

Empty space above and below Text elements in a ColumnLayout

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

Answers (2)

Mitch
Mitch

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.

TextMetrics

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.

Line height

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 }
        }
    }
}

Negative spacing

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" }
        }
    }
}

Text height

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

Programmer
Programmer

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

Related Questions