Dark Patate
Dark Patate

Reputation: 151

Using font awesome in QML: wrong characters

I would like to use font awesome font in my QML app. But it doesn't work very well.

First I use this method : https://github.com/QMLCommunity/font-awesome-qml But I got only two icons working, see the capture of my app.

Only the laptop and battery icons are displayed. The others (one top left, and others on each tab) got kanjis or other symbols.

After I also tried that solution : How to use Font Awesome in QML on the top left icon, whithout success.

Here the code of the notification bar :

RowLayout {
    anchors.fill: parent
    Label {
        font.pointSize: 10
        font.family: "fa-solid-900"
        text: "\uf071" + " Message"
    }

    Item {
        Layout.fillWidth: true
    }
    Label {
        font.pointSize: 10
        font.family: awesome.family
        text: awesome.loaded ? awesome.icons.fa_laptop : "x"
        Layout.alignment: Qt.AlignRight
    }

    Label {
        font.pointSize: 10
        font.family: awesome.family
        text: awesome.loaded ? awesome.icons.fa_battery_full + " 100 %" : "x"
        Layout.alignment: Qt.AlignRight
    }
}

PS: I used the 2nd link solution for the first icon, but the result is exactly the same with the first solution.

And the tab bar:

footer: TabBar {
    id: tabBar
    currentIndex: swipeView.currentIndex
    Material.theme: Material.Dark

    FontAwesome {
        id: awesome
        resource: "qrc:///controls/fa-solid-900.ttf"
    }

    TabButton {
        font.pointSize: 10
        font.family: awesome.family
        text: (awesome.loaded ? awesome.icons.fa_star : "x") + " " + "Général"
    }

    TabButton {
        font.pointSize: 10
        font.family: awesome.family
        text: (awesome.loaded ? awesome.icons.fa_cogs : "x") + " " + "Test"
    }
    TabButton {
        font.pointSize: 10
        font.family: awesome.family
        text: (awesome.loaded ? awesome.icons.fa_trophy : "x") + " " + "Match"
    }
}

How can I display the right icons each time?
Thanks in advance!

Upvotes: 1

Views: 1975

Answers (2)

Martin Höher
Martin Höher

Reputation: 735

I recently ran into the same issues and documented my approach in a blog post.

Basically, my issue was that starting with version 5, Font Awesome provides some of the icons in one font file with "regular" weight and one in a file with "solid" weight classes. However, when loading, both will register with a font name of "Font Awesome 5 Free" (assuming the free version is used).

I would have expected that it is possible to switch between the regular and solid icon sets by setting e.g. the bold property of a font in QML:

import QtQuick 2.0

Item {
    width: 100
    height: 100

    FontLoader {
        id: faRegular
        source: "./fa-regular-400.ttf"
    }
    FontLoader {
        id: faSolid
        source: "./fa-solid-900.ttf"
    }

    Column {
        width: parent.width

        Text {
            font.family: "Font Awesome 5 Free"
            font.bold: true // use "solid" variant
            text: "\uf073" // fa-calendar-alt
        }
        Text {
            font.family: "Font Awesome 5 Free"
            font.bold: false // use "regular" variant
            text: "\uf073" // fa-calendar-alt
        }
    }
}

Unfortunately, this did not work for me, as Qt merges both fonts and only either the regular or the solid variant was used (which causes some icons from not being rendered at all, especially if you use the regular variant which contains much less icons at least in the free version of the font).

My "solution" was to edit the solid font file (e.g. using FontForge) and change the font name to e.g. "Font Awesome 5 Free Solid". With this, I was able to load both variants of the font at the same time and switch between the two by using their font name like this:

import QtQuick 2.0

Item {
    width: 100
    height: 100

    FontLoader {
        id: faRegular
        source: "./fa-regular-400.ttf"
    }
    FontLoader {
        id: faSolid
        source: "./fa-solid-900.ttf"
    }

    Column {
        width: parent.width

        Text {
            font.family: faSolid.name // use solid variant
            text: "\uf073" // fa-calendar-alt
        }
        Text {
            font.family: faRegular.name // use regular variant
            text: "\uf073" // fa-calendar-alt
        }
    }
}

Upvotes: 4

Adrien Leravat
Adrien Leravat

Reputation: 2789

This is probably due to font merging when some characters cannot be resolved. You can try to load FontAwesome from C++ side

  1. Loading the font with a QFontDatabase

    int fontId = QFontDatabase::addApplicationFont(QStringLiteral("/path/to/font-awesome.ttf");
    
  2. Disabling merging on a new font

    QFont font("fa-solid-900"); // You can also use the fontId to get family name here
    font.setStyleStrategy(QFont::NoFontMerging);
    
  3. Exposing the font to QML with a QFont Q_PROPERTY or directly in the context

    Q_PROPERTY(QFont fontAwesome READ fontAwesome CONSTANT)
    

This is discussed in the Qt mailing list here

Upvotes: 1

Related Questions