Here's a small utility class that uses a simple markup extension to easily allow you to use Font Awesome glyphs in rich text on Qt. This allows widgets such as QLabel to use glyphs from the excellent Font Awesome font.
You will need:
The class is designed to embed Font Awesome in the application binary. You should set the file locations appropriately in the class.
QFontDatabase::addApplicationFont(":/FontAwesome/Free-Regular.otf");
QFontDatabase::addApplicationFont(":/FontAwesome/Free-Solid.otf");`
QFontDatabase::addApplicationFont(":/FontAwesome/Free-Brands.otf");`
Additionally, if you supply the _variables.scss
file (available on github, the class will parse this and you will be able to use the "fa-" style names to refer to glyphs rather than unicode numbers.
(Adjust the file locations as necessary)
Ensure that the Widget you want to use the font on is set to rich text mode:
myWidget->setTextFormat(Qt::RichText);
Simply pass the string you want to display into the function FAString::getString
, it accepts a markup inside it of the following syntax:
[far xxxx]
[far fa-<glpyh name>]
[fas xxxx]
[fas fa-<glpyh name>]
[fab xxxx]
[fab fa-<glpyh name>]
Where far
specifies the regular font, fas
is the strong font and fab
is the brands font. you will need to select the correct font according the the character you wish to use, this is displayed on the Font Awesome page when looking at a glyph
If you have supplied and loaded the _variables.scss
file, then you will be able to use the names as displayed on the website to refer to the icons.
myWidget->setText(FAString::richText("[fas f2f2] 43s"));
myWidget->setText(FAString::richText("[fas fa-stopwatch] 43s"));
Will display a stopwatch icon followed by the text 43s.
That's it!
(For even more convenience you could subclass QLabel
(for example as FALabel
) and override the setText
method to automatically call the FAString::richText
function)
// FAString.h
//
// Copyright (c) 2019 Adrian Carpenter
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
class FAString
{
private:
static FAString *getInstance()
{
static auto instance = new FAString();
return(instance);
}
FAString()
{
m_regularId = QFontDatabase::addApplicationFont(":/FontAwesome/Free-Regular.otf");
m_solidId = QFontDatabase::addApplicationFont(":/FontAwesome/Free-Solid.otf");
m_brandsId = QFontDatabase::addApplicationFont(":/FontAwesome/Free-Brands.otf");
if (QFontDatabase::applicationFontFamilies(m_regularId).count())
m_regularName = QFontDatabase::applicationFontFamilies(m_regularId).at(0);
if (QFontDatabase::applicationFontFamilies(m_solidId).count())
m_solidName = QFontDatabase::applicationFontFamilies(m_solidId).at(0);
if (QFontDatabase::applicationFontFamilies(m_brandsId).count())
m_brandsName = QFontDatabase::applicationFontFamilies(m_brandsId).at(0);
QFile scssFile(":/FontAwesome/_variables.scss");
if (scssFile.open(QFile::ReadOnly)) {
auto scssContent = QString::fromUtf8(scssFile.readAll());
if (!scssContent.isEmpty()) {
auto scssExpression = QRegularExpression(R"(\$fa-var-(?<name>.*)\:\W\\(?<code>([0-9]|[a-f]|[A-F]){1,4});)");
auto scssMatchIterator = scssExpression.globalMatch(scssContent);
while(scssMatchIterator.hasNext()) {
auto scssMatch = scssMatchIterator.next();
auto capturedTexts = scssMatch.capturedTexts();
if (capturedTexts.count()>=2) {
m_glyphMap["fa-"+capturedTexts.at(1)] = capturedTexts.at(2);
}
}
}
}
m_styleString = QString(R"(
<style>
.fas {
font-family:'%1';
font-weight:900
}
.far {
font-family:'%2';
font-weight:400
}
.fab {
font-family:'%3';
font-weight:400
}
.body {
position: absolute;
top: 50%;
}
</style>
)").arg(m_regularName, m_solidName, m_brandsName);
}
public:
static QString regularName()
{
return(getInstance()->m_regularName);
}
static QString solidName()
{
return(getInstance()->m_solidName);
}
static QString brandsName()
{
return(getInstance()->m_brandsName);
}
static QString richText(QString string)
{
auto expression = QRegularExpression(R"(\[(far|fas|fab) (([a-z]|\-|[0-9])*)\])");
auto match = QRegularExpressionMatch();
auto searchIndex = 0;
while(string.indexOf(expression, searchIndex, &match)>=0) {
if (match.capturedTexts().count()==4) {
auto richTextString = QString();
auto iconFont = match.capturedTexts().at(1);
auto iconId = match.capturedTexts().at(2);
auto iconCode = QString();
if (getInstance()->m_glyphMap.contains(iconId)) {
iconCode = getInstance()->m_glyphMap[iconId];
} else {
if ( (iconId.size()>=1) && ((iconId.size()<=4)) ) {
bool ok = false;
iconId.toInt(&ok, 16);
if (ok) {
iconCode = iconId;
}
}
}
if (iconCode.isNull()) {
richTextString = QString("");
} else {
richTextString = QString(R"(<span class="%1">&#x%2;</span>)").arg(iconFont, iconCode);
}
string.replace(match.capturedTexts().at(0), richTextString);
} else {
searchIndex += match.captured().length();
}
}
return(QString("<html>%1<body>%2</body></html>").arg(getInstance()->m_styleString).arg(string));
}
private:
int m_regularId;
int m_solidId;
int m_brandsId;
QString m_regularName;
QString m_solidName;
QString m_brandsName;
QString m_styleString;
QMap<QString, QString> m_glyphMap;
};