Conectar un motor para realizar cálculos y suministrar los datos a mostrar en la interfaz de usuario
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:
Ahora hemos conectado la clase que contiene la futura lógica a la aplicación, pero todavía no hace nada. Para cambiar esto, vamos a añadir una propiedad a la clase. Las propiedades son mucho más que una simple variable. Pueden informar a la interfaz de usuario de los cambios para que pueda actualizar las áreas correctas.
Right under the QML_SINGLETON macro, add a new Q_PROPERTY.
Esto puede parecer una gran cantidad de código para solo leer y escribir código desde el motor. Sin embargo, una mirada más cercana revela que leer la propiedad de la interfaz de usuario ya puede ejecutar cierta lógica (lo mismo ocurre cuando se escribe en ella). En este caso, informará automáticamente a la interfaz y al motor de los cambios.
La lectura y la escritura están basadas en los conceptos de las funciones getter y setter. Siga adelante y añada un nuevo atributo privado a la clase para contener los datos, así como las pertinentes funciones getter y setter.
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:
Como puede ver, cuando se llama al setter, se emite la señal y se informa a la interfaz de usuario y al motor del cambio.
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.
El código resultante en esta parte del archivo debería parecerse a esto:
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!".
¡Enhorabuena! Ha aprendido lo siguiente:
Cómo registrar tipos de motores en QML
Añadir nuevos elementos al archivo QML
Crear nuevas subclases de QObject
Cómo añadir propiedades y lo que hacen
Qué son las señales
Si quiere saber más sobre la integración entre QML y C++, le recomendamos que lea la documentación oficial de Qt.