Figuring out main.cpp
The role of main.cpp
QML is used for the front end of Kirigami applications, while the back end is usually written in C++, thanks to the language's speed and flexibility. The previous pages covered QML in depth; to make applications that do more than pure QML can, we need to understand our back-end C++ code.
Here we go over the main.cpp file we created in Setup with C++, to better understand what happens in the central C++ file of our application. It is a basic main.cpp, but the features we go over stay essential whatever kind of application you create.
What it does
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QUrl>
#include <QQuickStyle>
#include <KLocalizedQmlContext>
#include <KLocalizedString>
#include <KIconTheme>
int main(int argc, char *argv[])
{
KIconTheme::initTheme();
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("tutorial");
QApplication::setOrganizationName(QStringLiteral("KDE"));
QApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QApplication::setApplicationName(QStringLiteral("Kirigami Tutorial"));
QApplication::setDesktopFileName(QStringLiteral("org.kde.tutorial"));
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
}
QQmlApplicationEngine engine;
KLocalization::setupLocalizedContext(&engine);
engine.loadFromModule("org.kde.tutorial", "Main");
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
First we include a number of header files so we can use their functions: Qt headers that handle application logic and let us load QML files, and KDE Frameworks headers for icons and translations.
Before anything else, we call KIconTheme::initTheme(). It must be called before the application object is created. Under SonicDE, the platform theme already handles icons and colors, and the call does nothing more. In other environments, it applies the icon theme the user configured (Silver by default) through KIconThemes and makes the application's colors follow the system color scheme, so the application still looks right there.
We then create a QApplication instance called app. Passing argc and argv to the constructor is required. We use QApplication rather than QGuiApplication because the org.kde.desktop Qt Quick Controls style needs it: that style draws controls with the widget style, and isn't used with a QGuiApplication.
KLocalizedString::setApplicationDomain() sets the translation domain, the name of the catalog the application's translations are loaded from.
We also set some metadata about the application: the organization that created it, its domain, the name of the application, and the desktop file name that matches our org.kde.tutorial.desktop file. The first three are properties of QCoreApplication, which QApplication inherits from and which provides the event loop for applications with or without a GUI (so this metadata would still be set if we ran our program without the GUI).
We don't set a widget style: on SonicDE the platform theme applies the user's style (Silver by default). For Qt Quick Controls, we set the org.kde.desktop style with QQuickStyle::setStyle(), unless the user chose a style with the QT_QUICK_CONTROLS_STYLE environment variable. This style, from sonic-frameworks-quick-desktop-style, makes the controls in the window, such as buttons and checkboxes, follow the desktop style.
The QQmlApplicationEngine lets us load an application from a QML file. KLocalization::setupLocalizedContext() makes the i18n() functions available to the engine's QML code. Then, with engine.loadFromModule("org.kde.tutorial", "Main");, we load our QML from the import URI defined in CMake.
Next, we check that the engine loaded the QML file correctly by making sure the engine's rootObjects() list isn't empty. We can then run our application with app.exec().