Using font awesome in QML: wrong characters - qt

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!

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

This is probably due to font merging when some characters cannot be resolved. You can try to load FontAwesome from C++ side
Loading the font with a QFontDatabase
int fontId = QFontDatabase::addApplicationFont(QStringLiteral("/path/to/font-awesome.ttf");
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);
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

Related

Only some Font Awesome 5 icons work in Qt Qml

I am trying to show Font Aweseom 5 (5.10.2) icons in a Qt Qml label:
Label {
text: "\uf2bb" + " x " + "\uf002"
font.family: "Font Awesome 5 Free"
//font.weight: Font.Normal
}
On Windows all icons work as expected. But on all other platforms (macOS, Android, iOS) only some icons (for instance \uf2bb) are shown while others (\uf4b4) do not work and a simple rectangle is shown instead. But all icons work on all platforms when QWidgets are used.
I verified that the "Font Awesome 5 Free" font is installed in the QFontDatabase using this utility list view:
ListView {
anchors.fill: parent;
model: Qt.fontFamilies()
delegate: Item {
height: 40;
width: ListView.view.width
Label {
anchors.centerIn: parent
text: modelData;
}
}
}
Has anyone an idea why some icons work in Qml, while others don't?
Regards,
Either setting the font weight to Font.Black or the font's style name to "Solid" fixes the problem:
Label {
text: "\uf2bb" + " x " + "\uf002"
font.family: "Font Awesome 5 Free"
font.weight: Font.Black // this does the trick
}
Label {
text: "\uf2bb" + " x " + "\uf002"
font.family: "Font Awesome 5 Free"
font.styleName: "Solid" // this does the trick
}
I fixed this problem with https://fontforge.org/
On file fa-solid-900.ttf I modified the field WWS Family (under tab TTF Names) from Font Awesome 5 Free to Font Awesome 5 Free Solid
Maybe Qt for Android uses this field and without modification the value is the same for fa-regular-400.ttf and fa-solid-900.ttf
Hope it helps

how to get set font of text with another text's font

I have two Text items in qml and I want to set font of first text to the font of second text. How can I do that?
e.g
Text{
id:t1
//some code
//anchors ..etc
}
Text{
//set font = t1.font or something similar
}
You are almost there, you need to use colon : to assign the property:
Text {
id: txt1
font.bold: true
text: "Hello"
}
Text {
id: txt2
font: txt1.font
text: "World"
}

Qt QML font awesome not working on MAC and IOS

I am working on QML and loading the font awesome using FontLoader
FontLoader {
id: awesomeLoader
name: "awesome"
source: "qrc:/images/fontawesome-webfont.ttf"
}
Everything just find on Linux and Android, but it is not working on IOS and MAC, the font icon become empty rectangle.
This is how I use it :
Text {
font.pointSize: 20
font.family: "awesome"
anchors.fill: parent
text: isBackButton ? "\uf053" : "\uf0c9"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Is there anything special on MAC / IOS?
Make sure you're setting font.family:
font.family: awesomeLoader.name
One thing I noticed on Windows was that I could get icons to show up without setting font.family: "FontAwesome" (I forgot to do it), but when switching to macOS they would be broken.
It works in this way:
FontLoader {
id: awesomeLoader
//name: "awesome" (Comment or delete)
source: "qrc:/images/fontawesome-webfont.ttf"
}
In Text Item change font.family value to awesomeLoader.name (FontLoader id name)
Text {
font.pointSize: 20
font.family: awesomeLoader.name
anchors.fill: parent
text: isBackButton ? "\uf053" : "\uf0c9"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}

Default margin when using Text QML type

Consider this simple code sample:
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
color: "black"
Text {
text: "Hello World!"
font.family: "Helvetica"
font.pointSize: 24
color: "red"
}
}
Why is there a margin at the top? It seems that giving a custom font with a specific pixelSize gives a new size to the Text and breaks the alignement.
EDIT: well it seems that even without font there still is a margin.
A simpler solution would be to set the attribute y of the Text like this:
Text {
text: "Hello World!"
font.family: "Helvetica"
font.pixelSize: 42
color: "red"
y: -contentHeight + font.pixelSize
}
Bear in mind that if you set the property font.overline: true then it will be out of the Rectangle
I managed to remove this extra space with the use of FontMetrics but this solution seems way too complicated for this simple problem. Waiting for a better fix.
Window {
visible: true
color: "black"
FontMetrics {
id: fontmetrics24
font.pixelSize: 24
font.family: "Helvetica"
}
Text {
text: "Hello World!"
font.family: fontmetrics24.font.family
font.pointSize: fontmetrics24.font.pixelSize
color: "red"
y: - fontmetrics24.height * 0.21
}
}
I think this issue is related to this question. On macOS (Sierra), the window looks like this:
As ddriver pointed out, this is probably a bug and is already reported here.

How to find out which fonts are available in qml?

I would like to know which fonts I can use in a QML environment for the font.family property. Are these fonts system-specific or are they built into the framework? Is there any way to list all available fonts?
This code will list all the accepted font families:
ListView {
anchors.fill: parent;
model: Qt.fontFamilies()
delegate: Item {
height: 40;
width: ListView.view.width
Text {
anchors.centerIn: parent
text: modelData;
}
}
}
The fonts are system-specific so you should see what your system proposes.
If you are using QtCreator :
try putting your mouse over the end of your component name
Text <here> {
...
}
You should see a yellow light, click on it and you'll have an interface that allows to choose the font.
You can also access the interface with ctrl + alt + space while inside the component. Or with right click.
This is a system-specific list of fonts, but you can specify external font from resources (QRC)
You can improve the previous answer by adding this
Text {
font.family: modelData
anchors.centerIn: parent
text: modelData;
}

Resources