Specifying font for many Text-elements in Qt QML

12,311

Solution 1

Another possibility is to write a new QML component, that inherits from Text an sets some properties by default:

StyledText.qml

import QtQuick 1.0

Text {
    // set default values
    color: "blue"
    font.family: "Arial"
    font.bold: true
    font.italic: true
    font.pixelSize: 12
}

main.qml

import QtQuick 1.0

Rectangle {
    Row {
        spacing: 10

        Column {
            StyledText {
                text: "Foo1"
            }
            StyledText {
                text: "Bar1"
            }
            StyledText {
                text: "Baz1"
            }
        }

        Column {
            StyledText {
                text: "Foo2"
            }
            StyledText {
                text: "Bar2"
            }
            StyledText {
                text: "Baz2"
            }
        }
    }
}

Solution 2

In Qt 5.6 (at least, probably earlier too), you can use Qt.font() to dynamically allocate a font object and refer to it elsewhere. So, this works:

property font myFont: Qt.font({
    family: fontfamily,
    bold: fontbold,
    italic: fontitalic,
    pixelSize: fontpixelsize
});

Text
{   
    color: fontcolor
    font: parent.myFont
}

More info on Qt.font() here: https://doc-snapshots.qt.io/qt5-5.6/qml-qtqml-qt.html#font-method

Solution 3

One possible solution is to write a function, that iterates over the children of a passed element (for example a Column). In this function all the properties can be set:

import QtQuick 1.0

    Rectangle {
    Row {
        spacing: 10

        Column {
            id: col1

            Text {
                property bool useStyle: true
                text: "Foo1"
            }
            Text {
                property bool useStyle: true
                text: "Bar1"
            }
            Text {
                property bool useStyle: true
                text: "Baz1"
            }
        }

        Column {
            id: col2

            Text {
                property bool useStyle: true
                text: "Foo2"
            }
            Text {
                text: "not styled"
            }
            Text {
                property bool useStyle: true
                text: "Baz2"
            }
        }
    }

    function setTextStyle(parentElement) {
        for (var i = 0; i < parentElement.children.length; ++i) {
            console.log("t", typeof parentElement.children[i]);
            if (parentElement.children[i].useStyle) {  // apply style?
                parentElement.children[i].color = "blue";
                parentElement.children[i].font.family = "Arial"
                parentElement.children[i].font.bold = true;
                parentElement.children[i].font.italic = true;
                parentElement.children[i].font.pixelSize = 12;
            }
        }
    }

    // set style
    Component.onCompleted: {
        setTextStyle(col1);
        setTextStyle(col2);
    }
}

Each element, that contains the property useStyle that is set to true, gets styled. This is shorter, than assigning the style manually, but you can still define which elements should get styled or not.

Solution 4

Necro posting, but I feel it's still missing an up to date solution. FontMetrics will do the trick without using Qt.font(). You can declare it in your parent item or in a Singleton type and then you can bind the property to it.

Here there's an example

Item {
id: root

FontMetrics {
    id: fontMetrics
    font.family: "Arial"
    font.pixelSize: 24
}

property alias font: fontMetrics.font

Text { font: root.font }
Text { font: root.font }
}
Share:
12,311
larsmoa
Author by

larsmoa

Working on Reveal, a high performance CAD viewer based on WebGL.

Updated on June 05, 2022

Comments

  • larsmoa
    larsmoa about 2 years

    I have a widget specified through a QML file. This widget contains a top levelRectangle which contains two Columns. Each of these Columns contains many Text-elements. This QML widget is wrapped in a subclass of QDeclarativeView in C++.

    I want to specify the font for each of these Text-elements. Today I do this by specifying top-level properties:

    property string fontfamily: "Arial"
    property bool fontbold: false
    property bool fontitalic: false
    property int fontpixelsize: 11
    property string fontcolor: "White"
    

    and bind each Text-elements to these properties:

    Text
    {   
        color: fontcolor
        font.family: fontfamily
        font.bold: fontbold
        font.italic: fontitalic
        font.pixelSize: fontpixelsize
        ...
    }
    

    This isn't very elegant and new fields needs to be added every time I need support for something new (e.g. underlined fonts). I have not been able to declare a property of type font and bind to this instead (widget is blank and qmlviewer warns about "expected type after property").

    Is there a better way to specify a font for all Text-elements?

    Note! I'm handwriting the QML files.

  • Andrew Penkrat
    Andrew Penkrat over 7 years
    You can also expose a QFont from C++ and use it in QML.
  • gatis paeglis
    gatis paeglis over 3 years
    I think what is suggested here would be less memory efficient than using Qt.font()
  • Heath Raftery
    Heath Raftery over 2 years
    Alas, does not allow you override some properties. All required font properties must be set at once, which may lead to lots of Qt.font's across the application instead of specialising them where needed.
  • Martin Delille
    Martin Delille about 2 years
    The link is dead.
  • David K. Hess
    David K. Hess about 2 years
    @MartinDelille - thanks, I updated it.