Paramétrage et démarrage

Se préparer à la création de notre première application sous Kirigami.

Installation des paquets nécessaires

Avant de commencer, nous devons installer quelques éléments. Nous avons besoin d'un compilateur C++, des paquets de développement Qt et de Kirigami.

KubuntuKDE Neon
sudo apt install build-essential cmake extra-cmake-modules qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev kirigami2-dev libkf5i18n-dev gettext libkf5coreaddons-dev
ManjaroArch
sudo pacman -S base-devel extra-cmake-modules cmake qt5-base qt5-declarative qt5-quickcontrols2 kirigami2 ki18n kcoreaddons breeze
OpenSUSE
sudo zypper install --type pattern devel_C_C++
sudo zypper install cmake extra-cmake-modules libQt5Core-devel libqt5-qtdeclarative-devel libQt5QuickControls2-devel kirigami2-devel ki18n-devel kcoreaddons-devel qqc2-breeze-style
Fedora
sudo dnf groupinstall "Development Tools" "Development Libraries"
sudo dnf install cmake extra-cmake-modules qt5-qtbase-devel qt5-qtdeclarative-devel qt5-qtquickcontrols2-devel kf5-kirigami2-devel kf5-ki18n-devel kf5-kcoreaddons-devel qqc2-breeze-style

Des informations complémentaires pour les autres distributions sont disponibles ici.

Structure du projet

Bien qu'il existe des outils qui permettent de configurer facilement nos fichiers, nous allons les créer manuellement. Cela nous permettra de mieux comprendre les éléments qui vont constituer notre nouvelle application.

First we create our project folder. We are going to call ours "helloworld".

helloworld/
├── CMakeLists.txt
└── src/
    ├── CMakeLists.txt
    ├── main.cpp
    ├── resources.qrc
    └── contents/
        └── ui/
            └── main.qml

Within this folder we are going to create a src/ folder and CMakeLists.txt. It is generally considered good practice to place all our main code files in a src/ folder. Our src/ folder in turn will contain a folder named contents/, which itself contains a folder called ui/. Here is where we will create our QML files.

This is a KDE convention, but not all KDE projects use this structure. You are free to set things up differently, but you will have to take this into account when creating your CMakeLists.txt and resources.qrc files.

main.qml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Includes relevant modules used by the QML
import QtQuick 2.15
import QtQuick.Controls 2.15 as Controls
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami

// Provides basic features needed for all kirigami applications
Kirigami.ApplicationWindow {
    // Unique identifier to reference this object
    id: root

    // Window title
    // i18nc() makes a string translatable
    // and provides additional context for the translators
    title: i18nc("@title:window", "Hello World")

    // Set the first page that will be loaded when the app opens
    // This can also be set to an id of a Kirigami.Page
    pageStack.initialPage: Kirigami.Page {
        Controls.Label {
            // Center label horizontally and vertically within parent object
            anchors.centerIn: parent
            text: i18n("Hello World!")
        }
    }
}

C'est ici que nous allons gérer l'interface utilisateur de notre application.

Si vous connaissez un peu le langage Javascript, alors une grande partie de QML vous semblera familière (bien qu'il ait ses propres particularités). La documentation de Qt propose une quantité importante de documents sur ce langage si vous avez envie d'essayer quelque chose par vous-même. Au cours de ces tutoriels, nous porterons une grande partie de notre attention sur notre code QML, où nous pourrons utiliser Kirigami pour en tirer le meilleur parti.

For now, let's focus on main.qml. First we import a number of important modules:

  • QtQuick, the standard library used in QML applications.
  • QtQuick Controls, which provides a number of standard controls we can use to make our applications interactive.
  • QtQuick Layouts, which provides tools for placing components within the application window.
  • Kirigami , which provides a number of components suited for creating applications that work across devices of different shapes and sizes.

We then come to our base element, Kirigami.ApplicationWindow , which provides some basic features needed for all Kirigami applications. This is the window that will contain each of our pages, the main sections of our UI.

We then set the window's id property to "root". IDs are useful because they let us uniquely reference a component, even if we have several of the same type.

We also set the window title property to "Hello World". You'll notice that we have wrapped our "Hello World" string in a function called i18nc(), where we detail the context of the string as well as the string itself.

We then set the first page of our page stack. Most Kirigami applications are organised as a stack of pages, each page containing related components suited to a specific task. For now, we are keeping it simple, and sticking to a single page. pageStack is an initially empty stack of pages provided by Kirigami.ApplicationWindow , and with pageStack.initialPage: Kirigami.Page {...} we set the first page presented upon loading the application to a Kirigami.Page . This page will contain all our content.

Finally, we include in our page a Controls.Label that lets us place text on our page. We use anchors.centerIn: parent to center our label horizontally and vertically within our parent element. In this case, the parent component of our label is Kirigami.Page . The last thing we need to do is set its text: text: i18n("Hello World!").

main.cpp

main.cpp handles the "business logic" of our application. C++ is handy because it is flexible and fast, even if it is more involved than other programming languages.

Le fichier « main.cpp » est aussi le point d'entrée de notre application. Les deux parties de notre projet, le moteur et l'interface utilisateur, sont toutes deux configurées et démarrées ici.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QUrl>
#include <KLocalizedContext>
#include <KLocalizedString>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);
    KLocalizedString::setApplicationDomain("helloworld");
    QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
    QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
    QCoreApplication::setApplicationName(QStringLiteral("Hello World"));

    QQmlApplicationEngine engine;

    engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    if (engine.rootObjects().isEmpty()) {
        return -1;
    }

    return app.exec();
}

For now, we don't need to go into too much detail regarding what our main.cpp code does, but its role will grow significantly more important once we decide to add more complex functionality to our application in the future. If you want to get ahead, you can read more about how this main.cpp works in this page.

resources.qrc

Our resources.qrc is a Qt Resource file. It contains the list of all QML files as well as other files (like custom icons) that will be included in the binary.

1
2
3
4
5
<RCC>
    <qresource prefix="/">
        <file alias="main.qml">contents/ui/main.qml</file>
    </qresource>
</RCC>

Veuillez regarder la ligne « contents/ui/main.qml ». Elle fournit des détails sur quels fichiers QML vont être inclus dans le processus de compilation. Dans notre cas, nous utilisons seulement « main.qml ». Mais, si nous devions ajouter plus de fichiers QML à notre code, nous devrions nous assurer de les inclure dans le fichier « resources.qrc » en ajoutant une autre ligne comme celle-ci.

This resource file lets us use the "qrc:" + "/main.qml" path in our main.cpp, instead of needing to specify the whole "contents/ui/main.qml" path.

CMakeLists.txt

CMakeLists.txt files are needed to use KDE's build system of choice, CMake. The CMakeLists.txt file in our top-level folder is going to specify some of our application's characteristics. It also includes some of the dependencies we need in order to compile our project.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cmake_minimum_required(VERSION 3.16)
project(helloworld)

set(KF_MIN_VERSION "5.68.0")
set(QT_MIN_VERSION "5.12.0")

find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)

set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})

include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)

find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui QuickControls2 Widgets)
find_package(KF5 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 I18n CoreAddons)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_subdirectory(src)

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

The CMakeLists.txt defines how to build your projects. Most of the content here is just to bootstrap your project. You can read a line-by-line, in-depth explanation of what this CMakeLists file does here.

The most important thing to keep in mind is that the Qt and KDE Frameworks dependencies are managed with find_package(). You will have to modify these lines and include any additional components that you decide to use during the development of your application.

The final line, add_subdirectory(src), points CMake to the helloworld/src/ directory, where our source code is located. Let's delve into the helloworld/src/CMakeLists.txt file in there.

1
2
add_executable(helloworld main.cpp resources.qrc)
target_link_libraries(helloworld Qt5::Quick Qt5::Qml Qt5::Gui Qt5::QuickControls2 Qt5::Widgets KF5::Kirigami2 KF5::I18n)

Celui-ci est beaucoup plus court ! Voyons ce qu'il fait :

Maintenant que « CMake » a été pris en charge, regardons les fichiers avec lesquels nous allons travailler la majorité de notre temps.

Compilation et exécution de l'application

We are almost at the finish line. The last thing we need to do is build and compile our application. To do that, we need to enter our helloworld/ folder in our terminal application of choice and run the following commands:

cmake -B build/
cmake --build build/

Et lancez le avec :

./build/bin/helloworld

Voilà! Now you will see your very first Kirigami app appear before your very own eyes.

 ! Une capture d'écran de l'application générée avec Kirigami