Anslut bakgrundskod för att göra beräkningar och tillhandahålla användargränssnittet med data att visa
För att integrera logik i programmet behöver vi C++ bakgrundsklasser som kan utföra de viktiga beräkningarna. Att skriva logik i QML-filer avråds från, så försök att flytta så mycket som möjligt till bakgrundskoden, så att QML bara används för att visa användargränssnittet.
Skapa först deklarationsfilen som ska ha kod exponerad till QML, närmare bestämt typen Backend:
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);};
Det finns två saker som behövs för att exponera C++ kod för QML, och en av dem är helt enkelt att använda makrot QML_ELEMENT, tillgängligt i deklarationsfilen <QtQml/qqmlregistration.h>.
Backend skapas som en singleton, vilket innebär att den bara skapas en gång och existerar under hela programmets livslängd. För det använder vi makrot QML_SINGLETON.
src/components/backend.cpp
Vi kan lägga till vår ursprungliga kod för konstruktorn i backend.cpp:
Hädanefter är den känd för QML som QML-typen Backend. Den finns i en modul som kallas org.kde.tutorial.components.
Det betyder att bara genom att lägga till importen i en QML-fil är det möjligt att använda koden som exponerats från C++:
importorg.kde.tutorial.components
För att börja från början med den befintliga programkoden, skapa en ny QML-komponent som innehåller en tom sida:
1
2
3
4
5
6
7
importorg.kde.kirigamiasKirigamiimportorg.kde.tutorial.componentsKirigami.Page{title:"Exposing to QML Tutorial"// ...
}
src/Main.qml
För att faktiskt visa den nya sidan, låt oss skapa ett menyalternativ som skickar den nya sidan till programmet, bara så att vi kan testa modellen enklare.
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
Lägg till sist till de nyskapade backend.h, backend.cpp och ExposePage.qml i CMake:
Nu har vi anslutit klassen som innehåller den framtida programlogiken, men den gör inte ännu någonting. För att ändra det, låt oss lägga till en egenskap i klassen. Egenskaper är mycket mer än en enkel variabel. De kan informera användargränssnittet om ändringar så att det kan uppdatera riktiga områden.
Direkt under makrot QML_SINGLETON, lägg till en ny Q_PROPERTY.
Det verkar som rätt mycket kod för att bara läsa och skriva en del bakgrundskod. Men en närmare titt avslöjar att det redan kan utföra logik när egenskapen läses av användargränssnittet, och även när den skrivs till. I detta fall, informerar den automatiskt både förgrunden och bakgrunden om ändringar.
Läsning och skrivning är baserade på hämtnings- och tilldelningsfunktioner, så lägg till en ny privat egenskap i din klass, och lägg till hämtnings- och tilldelningsfunktioner.
Den första funktionen är hämtningsfunktionen,den andra är tilldelningsfunktionen, och den tredje en signal som skickas när egenskapen ändras. De motsvarar delarna READ, WRITE och NOTIFY av ovanstående Q_PROPERTY.
Resultatet ska se ut så här:
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
Signalen behöver ingen implementering i filen backend.cpp, eftersom den inte gör mycket mer än att skickas, men hämtnings- och tilldelningsfunktionen behöver implementeras på liknande sätt som det följande:
Som du kan se, när tilldelningsfunktionen anropas, skickas signalen, och informerar användargränssnittet och bakgrundskoden om ändringen.
src/components/ExposePage.qml
För att visa texten, lägg till en Kirigami.Heading i src/components/ExposePage.qml under egenskapen title för elementet Kirigami.Page, som redan finns i mallen.
Den resulterande koden i den delen av filen ska se ut så här:
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}}
Kompilera och starta om programmet. Du ser att den nya sidan har en centrerad rubrik med texten "Hello World!".
Gratulerar, du har lärt dig:
Hur man registrerar gränssnittstyper i QML
Att lägga till nya element i QML-filen
Att skapa nya QObject delklasser
Hur man lägger till egenskaper och vad de gör
Vad signaler är
Om du vill veta mer om integreringen mellan QML och C++, rekommenderar vi att läsa den officiella Qt-dokumentationen.