Podłącz logikę do swojego interfejsu użytkownika QML
Podłącz silnik, aby wykonać obliczenia i zasilić twój interfejs użytkownika danymi do wyświetlenia
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:
Teraz połączyliśmy klasę przechowującą przyszłą logikę z aplikację, lecz nadal nie robi ona nic. Aby to zmienić, dodajmy właściwość do klasy. Właściwości to coś więcej niż prosta zmienna. Powiadamiają interfejs użytkownika o zmianach tak, aby mógł się uaktualnić w odpowiednich obszarach.
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:
Jak widzisz, gdy setter jest wywoływany, to sygnał zostanie wysłany i powiadomi interfejs oraz silnik o zmianie.
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.
Kod wynikowy w tej części pliku powinien wyglądać następująco:
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!".
Gratulacje, nauczyłeś się:
Jak zarejestrować rodzaje silnika w QML
Dodaj nowe rzeczy do pliku QML
Stwórz nowe podklasy QObject
Jak dodać właściwości i co one robią
Czym są sygnały
If you want to know more about the integration between QML and C++, we recommend reading the official Qt documentation.