Using Material Design Icons in Qt Quick
When the Qt Project released Qt Quick Controls 2 with a new theme inspired by Google's Material Design guidelines, I felt like the look wouldn't be complete without the matching icon set. Here's how I got the icon theme to work with Qt.
Update: 5/30/2021: I've pushed a new version of this to GitHub, which includes definitions for all the icons available at the time of the update. I've also bundled the corresponding font file as well, for convenience. The JavaScript portion is now MIT licensed, with the font file being distributed under the SIL Open Font License, to match the Material Design Icons project.
Since I didn't want to import each icon as an individual image resource, I turned to the Material Design Icons font. While the project caters primarily to Web apps, it provides a single font file (distributed in a handful of formats) that contains all the Material Design icons that Google has released, along with a number of community-made icons that complement the theme.
Add the font file as a resource in our Qt project's QRC file, and register the font in the application's font database. If we started with the basic QML application template from Qt Creator, we could do this in the main.cpp
file, as illustrated below:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QFontDatabase>
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QFontDatabase::addApplicationFont(":/materialdesignicons-webfont.ttf");
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
To actually use the icons in our application, we have to consider two implications of the choice to import them as a single font file, rather than as image resources. First, we can only access the icons from QML items that display text, such as the Text
or Label
element, or the Button
control. This complicates the situation if we need a button control that shows both icon(s), and text, for example, though we could define a custom QML control to address this.
The other, more pressing concern is the fact that we have to know the specific Unicode character that corresponds to any icon that we want to display. The Material Design Icons project provides a CSS file that maps each icon to its own CSS class. To get a similar interface for our QML apps, I created a JavaScript object that matches the CSS class names with their corresponding Unicode characters.
To use the JavaScript object, we have to add the Icon.js
file to the project, and import it into any QML file that needs access to icon names. I usually import the file as MdiFont
, so I can get to the icons from MdiFont.Icon.<iconName>
. To demonstrate, I've included the QML source that creates the sample app pictured at the top of this post:
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import "Icon.js" as MdiFont
ApplicationWindow {
visible: true
width: 720
height: 480
title: qsTr("Material Design Icons in QML")
Rectangle {
id: header
color: "#3f51b5"
height: 72
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
Text {
font.family: "Roboto"
font.pointSize: 24
text: qsTr("Material Design Icons in QML")
color: "#ffffff"
anchors.left: parent.left
anchors.leftMargin: 16
anchors.top: parent.top
anchors.topMargin: 20
}
}
Rectangle {
color: "#e0e0e0"
anchors.top: header.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
RowLayout {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
spacing: 48
IconLabel {
text: MdiFont.Icon.cloud
}
IconLabel {
text: MdiFont.Icon.lambda
}
IconLabel {
text: MdiFont.Icon.signCaution
}
IconLabel {
text: MdiFont.Icon.recycle
}
}
}
}
To keep things clean, consistent, and DRY, I banished the basic formatting details to my customized IconLabel
element:
IconLabel.qml
import QtQuick 2.7
Text {
font.family: "Material Design Icons"
font.pixelSize: 96
opacity: 0.75
}
With this technique, you can deliver an authentic look and feel in your Qt apps that target the Android platform. You can download the JavaScript object mentioned earlier from my GitHub project. I've made the file available under the terms of the SIL Open Font License, version 1.1, to match the license of the Material Design Icons font.
Lead image is a screenshot of a sample QML application with Material Design icons. Wallpaper image © 2012 by Flickr user Hemlit, released under the Creative Commons Attribution 2.0 Generic License. Wallpaper is available here. Icon choices not intended to confirm Half-Life 3.