Connecter une logique à votre interface utilisateur QML
Connectez un moteur pour réaliser des calculs et fournir à votre interface utilisateur les données à afficher.
To integrate logic into the application, we need C++ backend classes that can do the important calculations. Writing logic in the QML files is discouraged, so try to move as much as possible to the backend such that QML is used only for displaying the user interface.
First, create the header file that will have code exposed to QML, namely the Backend type:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
#include<QObject>#include<qqmlintegration.h>classBackend:publicQObject{Q_OBJECTQML_ELEMENTQML_SINGLETONpublic:explicitBackend(QObject*parent=nullptr);};
There are two things needed to expose C++ code to QML, and one of them is simply using the QML_ELEMENT macro, available in the <QtQml/qqmlregistration.h> header.
The backend will be created as a singleton, which means it will only be created once and exist for the whole duration of the application lifetime. For this, we use the QML_SINGLETON macro.
src/components/backend.cpp
We can add our initial code for the constructor to backend.cpp:
globalDrawer:Kirigami.GlobalDrawer{isMenu:trueactions:[Kirigami.Action{text:i18n("Exposing to QML")icon.name:"kde"onTriggered:pageStack.push(Qt.createComponent("org.kde.tutorial.components","ExposePage"))},Kirigami.Action{text:i18n("Quit")icon.name:"application-exit-symbolic"shortcut:StandardKey.QuitonTriggered:Qt.quit()}]}
src/components/CMakeLists.txt
Lastly, add the newly created backend.h, backend.cpp and ExposePage.qml to CMake:
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 QML_SINGLETON macro, add a new Q_PROPERTY.
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.
The first function is the getter, the second the setter, and the third a signal that is emitted when the property is changed. They match the READ, WRITE and NOTIFY parts of the above Q_PROPERTY.
The result should look like the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#pragma once
#include<QObject>#include<qqmlintegration.h>classBackend:publicQObject{Q_OBJECTQML_ELEMENTQML_SINGLETONQ_PROPERTY(QStringintroductionTextREADintroductionTextWRITEsetIntroductionTextNOTIFYintroductionTextChanged)public:explicitBackend(QObject*parent=nullptr);QStringintroductionText()const;voidsetIntroductionText(constQString&introductionText);Q_SIGNALvoidintroductionTextChanged();private:QStringm_introductionText=QStringLiteral("Hello World!");};
src/components/backend.cpp
The signal doesn't need any implementation in the 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:
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.
src/components/ExposePage.qml
To display the text, add a Kirigami.Heading to src/components/ExposePage.qml under the title property of the Kirigami.Page component we added to the code.
Le code résultant dans cette partie du fichier devrait ressembler à ceci :
1
2
3
4
5
6
7
8
9
10
importorg.kde.kirigamiasKirigamiimportorg.kde.tutorial.componentsKirigami.Page{title:"Exposing to QML Tutorial"Kirigami.Heading{anchors.centerIn:parenttext:Backend.introductionText}}
#pragma once
#include<QObject>#include<qqmlintegration.h>classBackend:publicQObject{Q_OBJECTQML_ELEMENTQML_SINGLETONQ_PROPERTY(QStringintroductionTextREADintroductionTextWRITEsetIntroductionTextNOTIFYintroductionTextChanged)public:explicitBackend(QObject*parent=nullptr);QStringintroductionText()const;voidsetIntroductionText(constQString&introductionText);Q_SIGNALvoidintroductionTextChanged();private:QStringm_introductionText=QStringLiteral("Hello World!");};
importorg.kde.kirigamiasKirigamiimportorg.kde.tutorial.componentsKirigami.Page{title:"Exposing to QML Tutorial"Kirigami.Heading{anchors.centerIn:parenttext:Backend.introductionText}}
Now compile and start your program again. You'll see that the new page has a centered Heading saying "Hello World!".
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
If you want to know more about the integration between QML and C++, we recommend reading the official Qt documentation.