Connettere la logica all'interfaccia in QML
Per integrare la logica nell'applicazione abbiamo bisogno delle classi del motore C++, che possono eseguire i calcoli importanti. La logica della scrittura nei file QML è scoraggiata, quindi cerca di scrivere il motore da un'altra parte, in modo che il file QML venga usato solamente per visualizzare l'interfaccia: quello è il suo compito.
Per la tua nuova classe del motore crea due file chiamati backend.cpp
e backend.h
. Non dimenticarti di aggiungere il nuovo file cpp all'eseguibile, in src/CMakeLists.txt
, accanto a main.cpp.
Aggiungi il seguente contenuto al nuovo file di intestazione (backend.h
):
#pragma once
#include <QObject>
class Backend : public QObject
{
Q_OBJECT
public:
explicit Backend(QObject *parent = nullptr);
};
Allo stesso modo il file backend.cpp
contenente le definizioni è attualmente vuoto. Dovrebbe contenere qualcosa di simile a:
#include "backend.h"
Backend::Backend(QObject *parent)
: QObject(parent)
{
}
Per adesso l'interfaccia non sa niente della tua classe del motore; per modificare questa situazione dobbiamo registrare il nuovo tipo in main.cpp
. Il motore verrà creato come singleton, cioè verrà creato solo una volta ed esisterà per tutto il tempo, dall'avvio dell'applicazione alla sua chiusura.
Right after creating the QQmlApplicationEngine, add the type registration to main.cpp
as follows:
Backend backend;
qmlRegisterSingletonInstance<Backend>("org.kde.example", 1, 0, "Backend", &backend);
Non dimenticarti di includere il nuovo file di intestazione all'inizio di main.cpp
.
Da adesso in poi il motore sarà conosciuto da QML come Backend
: è contenuto in un modulo chiamato org.kde.example
. Dal momento che il modulo è parte dell'applicazione non ti devi preoccupare della versione, rimani alla `1.0 ed usala costantemente nella tua applicazione.
Importa il nuovo modulo in main.qml
:
import org.kde.example 1.0
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.
Right under the Q_OBJECT macro, add a new Q_PROPERTY.
Q_PROPERTY(QString introductionText READ introductionText WRITE setIntroductionText NOTIFY introductionTextChanged)
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.
private:
QString m_introductionText = "Hello World!";
Aggiungi nella sezione public
public:
QString introductionText() const;
void setIntroductionText(const QString &introductionText);
Q_SIGNAL void introductionTextChanged();
The first function is the getter, the second the setter, and the third a signal that is emitted when the property is changed. The signal doesn't need any implementation in 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:
QString Backend::introductionText() const
{
return m_introductionText;
}
void Backend::setIntroductionText(const QString &introductionText)
{
m_introductionText = introductionText;
Q_EMIT introductionTextChanged();
}
Come puoi vedere, quando viene chiamata la proprietà viene emesso il segnale, che informa l'interfaccia e il motore delle modifiche.
To display the text, add a heading to main.qml
under the title
property of the Kirigami.Page element already contained in the template.
Il codice risultante in quella parte di file dovrebbe assomigliare a questo:
// ...
Kirigami.Page {
title: i18n("develop.kde.org tutorial")
Kirigami.Heading {
anchors.centerIn: parent
text: Backend.introductionText
}
actions: [
Kirigami.Action {
// ...
}
]
}
Ora compila e avvia nuovamente il programma.
Congratulazioni, hai imparato:
- Come registrare i tipi di motore in QML
- Ad aggiungere nuovi elementi al file QML
- A creare nuove sotto-classi QObject
- Come aggiungere delle proprietà, e che cosa fanno
- Che cosa sono i segnali
If you want to know more about the integration between QML and C++, we recommend reading the official Qt documentation.