Connecter une logique à votre interface utilisateur QML

Connectez un moteur pour réaliser des calculs et fournir à votre interface utilisateur les données à afficher.

Pour intégrer la logique dans l'application, nous avons besoin de classes du moteur C++, pouvant effectuer les calculs importants. L'écriture de la logique dans les fichiers QML est déconseillée. Essayez donc de transférer le plus possible vers le moteur, de sorte que QML ne soit utilisé que pour afficher l'interface utilisateur, ce pour quoi il est le plus adapté.

Pour votre nouvelle classe de moteur, veuillez créer deux nouveaux fichiers appelés « backend.cpp » et « backend.h ». N'oubliez pas d'ajouter le nouveau fichier « cpp » à l'exécutable dans le fichier « src/CMakeLists.txt », à côté du fichier « main.cpp ».

Ajoutez le contenu suivant au nouveau fichier d'en-tête ( « backend.h » ) :

#pragma once

#include <QObject>

class Backend : public QObject
{
    Q_OBJECT

public:
    explicit Backend(QObject *parent = nullptr);
};

The backend.cpp file containing the definitions is similarly empty right now, it should contain something like the following:

#include "backend.h"

Backend::Backend(QObject *parent)
    : QObject(parent)
{

}

Actuellement, l'interface utilisateur ne connaît pas la classe de votre moteur. Pour changer cela, nous devons enregistrer le nouveau type dans « main.cpp ». Le moteur sera créé comme un singleton, ce qui signifie qu'il ne sera créé qu'une seule fois et existera pendant toute la durée de l'application, de son démarrage à sa fermeture.

Right after creating the QQmlApplicationEngine , add the type registration to main.cpp as follows:

    Backend backend;
    qmlRegisterSingletonInstance<Backend>("org.kde.example", 1, 0, "Backend", &backend);

N'oubliez pas d'inclure le nouveau fichier d'en-tête en haut de « main.cpp ».

From now on, the backend will be known to QML as Backend. It is contained in a module called org.kde.example. Since the module is part of the application, you don't need to worry about versioning it, just stay with 1.0 and use it consistently throughout the application.

Dans le fichier « main.qml », importez le nouveau module :

import org.kde.example 1.0

Maintenant, nous avons connecté la classe contenant la future logique de l'application, mais elle ne fait toujours rien. Pour changer cela, ajoutons une propriété à la classe. Les propriétés sont bien plus qu'une simple variable. Elles peuvent informer l'interface utilisateur de tout changement afin qu'elle puisse mettre à jour les bonnes zones.

Right under the Q_OBJECT macro, add a new Q_PROPERTY .

Q_PROPERTY(QString introductionText READ introductionText WRITE setIntroductionText NOTIFY introductionTextChanged)

This may seem like a lot of code to just read and write some code from the backend. However, a closer look reveals that reading the property from the UI can already run some logic—same when it is written to. In this case, it will automatically inform the frontend and backend of changes.

The reading and writing is based on the concept of getter and setter functions. Go ahead and add a new private attribute to your class that holds the data, as well as the relevant getter and setter functions.

private:
    QString m_introductionText = "Hello World!";

Dans la section publique, ajoutez

public:
    QString introductionText() const;
    void setIntroductionText(const QString &introductionText);
    Q_SIGNAL void introductionTextChanged();

The first function is the getter, the second the setter, and the third a signal that is emitted when the property is changed. The signal doesn't need any implementation in backend.cpp file, since it doesn't do much more than being emitted, but the getter and setter need to be implemented similar to the following:

QString Backend::introductionText() const
{
    return m_introductionText;
}

void Backend::setIntroductionText(const QString &introductionText)
{
    m_introductionText = introductionText;
    Q_EMIT introductionTextChanged();
}

Comme vous pouvez le voir, lorsque le transmetteur est appelé, le signal sera émis et informera l'interface utilisateur et le moteur de ce changement.

To display the text, add a heading to main.qml under the title property of the Kirigami.Page element already contained in the template.

Le code résultant dans cette partie du fichier devrait ressembler à ceci :

...
Kirigami.Page {
    title: i18n("develop.kde.org tutorial")

    Kirigami.Heading {
        anchors.centerIn: parent
        text: Backend.introductionText
    }

    actions {
        main: Kirigami.Action {
            ...
        }
    }
}

Maintenant, compiler et lancer votre programme à nouveau.

Félicitations, vous êtes formé :

  • Comment enregistrer des types de moteurs dans QML
  • Ajouter de nouveaux éléments au fichier QML
  • Créer des sous-classes nouvelles de QObject
  • Comment ajouter des propriétés et ce qu'elles font
  • Quels signaux sont

Si vous souhaitez en savoir plus sur l'intégration entre QML et C++, nous vous recommandons la lecture de la documentation officielle de Qt.