Connettere un motore per svolgere i calcoli e per fornire all'interfaccia utente i dati da visualizzare
Per integrare la logica nell'applicazione, abbiamo bisogno di classi backend C++ in grado di eseguire i calcoli importanti. Si sconsiglia di scrivere la logica nei file QML, quindi provare a spostarsi il più possibile sul backend in modo tale che QML venga utilizzato solo per visualizzare l'interfaccia utente.
Innanzitutto, crea il file di intestazione che avrà il codice esposto a QML, vale a dire il tipo 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);};
Sono necessarie due cose per esporre il codice C++ a QML e una di queste è semplicemente utilizzare la macro QML_ELEMENT, disponibile nell'intestazione <QtQml/qqmlregistration.h>.
Il backend verrà creato come singleton, il che significa che verrà creato una sola volta ed esisterà per l'intera durata della vita dell'applicazione. Per questo, utilizziamo la macro QML_SINGLETON.
src/components/backend.cpp
Possiamo aggiungere il nostro codice iniziale per il costruttore a backend.cpp:
D'ora in poi, il backend sarà noto a QML come tipo QML "Backend". È contenuto in un modulo chiamato org.kde.tutorial.components.
Ciò significa che semplicemente aggiungendo l'importazione in un file QML, è possibile utilizzare il codice esposto da C++:
importorg.kde.tutorial.components
Per iniziare da zero utilizzando il codice dell'applicazione esistente, crea un nuovo componente QML che contenga una pagina vuota:
1
2
3
4
5
6
7
importorg.kde.kirigamiasKirigamiimportorg.kde.tutorial.componentsKirigami.Page{title:"Exposing to QML Tutorial"// ...
}
src/Main.qml
Per mostrare effettivamente la nuova pagina, creiamo un'opzione di menu che invia la nuova pagina all'applicazione, solo così possiamo testare il modello più facilmente.
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
Infine, aggiungi i file backend.h, backend.cpp e ExposePage.qml appena creati a CMake:
Ora abbiamo connesso la classe che contiene la logica futura all'applicazione, ma ancora non fa nulla. Per modificare ciò, aggiungiamo una proprietà alla classe. Le proprietà sono molto di più di una semplice variabile: possono informare l'interfaccia sulle modifiche, in modo che essa possa aggiornare le aree giuste.
Proprio sotto la macro QML_SINGLETON, aggiungi una nuova Q_PROPERTY.
Potrebbe sembrare un sacco di codice da leggere e scrivere solo del codice dal backend. Tuttavia, uno sguardo più attento rivela che la lettura della proprietà dall'interfaccia utente può già eseguire una certa logica, lo stesso quando viene scritta. In questo caso, informerà automaticamente il frontend e il backend delle modifiche.
La lettura e la scrittura si basano sul concetto di funzioni getter e setter. Vai avanti e aggiungi un nuovo attributo privato alla tua classe che contiene i dati, nonché le relative funzioni getter e setter.
Aggiungi una nuova sezione privata con quanto segue:
La prima funzione è il getter, la seconda il setter e la terza un segnale che viene emesso quando la proprietà viene modificata. Corrispondono alle parti READ, WRITE e NOTIFY di "Q_PROPERTY" sopra.
Il risultato dovrebbe essere simile al seguente:
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
Il segnale non necessita di alcuna implementazione nel file backend.cpp, poiché non fa molto altro che essere emesso, ma getter e setter devono essere implementati in modo simile al seguente:
Come puoi vedere, quando viene chiamata la proprietà viene emesso il segnale, che informa l'interfaccia e il motore delle modifiche.
src/components/ExposePage.qml
Per visualizzare il testo, aggiungi un Kirigami.Heading a src/components/ExposePage.qml sotto la proprietà titolo del Componente Kirigami.Page che abbiamo aggiunto al codice.
Il codice risultante in quella parte di file dovrebbe assomigliare a questo:
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}}
Ora compila e avvia nuovamente il programma. Vedrai che la nuova pagina ha un'intestazione centrata che dice "Hello World!".