Conectar la lógica a la interfaz de usuario QML

Conectar un motor para realizar cálculos y suministrar los datos a mostrar en la interfaz de usuario

Para integrar la lógica en la aplicación, necesitamos clases de motores C++ que puedan realizar los cálculos importantes. No se aconseja escribir la lógica en los archivos QML, por lo que debería intentar mover todo lo que le sea posible al motor, de modo que QML se use exclusivamente para mostrar la interfaz de usuario, que es lo que hace mejor.

Para la nueva clase de motor, cree dos archivos llamados backend.cpp y backend.h. No se olvide de añadir el nuevo archivo cpp al ejecutable en src/CMakeLists.txt, junto a main.cpp.

Añada el siguiente contenido al nuevo archivo de cabecera (backend.h):

#pragma once

#include <QObject>

class Backend : public QObject
{
    Q_OBJECT

public:
    explicit Backend(QObject *parent = nullptr);
};

El archivo backend.cpp que contiene las definiciones también está vacío ahora; debe contener algo similar a lo siguiente:

#include "backend.h"

Backend::Backend(QObject *parent)
    : QObject(parent)
{

}

Hasta ahora, la interfaz de usuario no sabe nada sobre la clase del motor. Para cambiar esto, necesitamos registrar el nuevo tipo en main.cpp. El motor se creará como singleton, lo que significa que solo se creará una vez y existirá durante todo el tiempo, desde que se inicia la aplicación hasta que se cierra.

Después de crear el QQmlApplicationEngine , añada el registro de tipo a main.cpp de este modo:

    Backend backend;
    qmlRegisterSingletonInstance<Backend>("org.kde.example", 1, 0, "Backend", &backend);

No olvide incluir el nuevo archivo de cabecera al principio de main.cpp.

A partir de este momento, QML conocerá el motor como Backend. Está contenido en un módulo llamado org.kde.example. Como el módulo es parte de la aplicación, no tiene que preocuparse por su número de versión: solo tiene que quedarse con 1.0 y usarlo de forma consistente en toda la aplicación.

En main.qml, importe el nuevo módulo:

import org.kde.example 1.0

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.

Justo debajo de la macro Q_OBJECT , añada una nueva 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!";

En la sección public, añada

public:
    QString introductionText() const;
    void setIntroductionText(const QString &introductionText);
    Q_SIGNAL void introductionTextChanged();

La primera función es el getter, la segunda es el setter y la tercera es una señal que se emite cada vez que se cambie la propiedad. La señal no necesita estar implementada en el archivo backend.cpp, ya que no hace otra cosa que emitirse, aunque el getter y el setter deben implementarse de un modo similar al siguiente:

QString Backend::introductionText() const
{
    return m_introductionText;
}

void Backend::setIntroductionText(const QString &introductionText)
{
    m_introductionText = introductionText;
    Q_EMIT introductionTextChanged();
}

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.

To display the text, add a heading to main.qml under the title property of the Kirigami.Page element already contained in the template.

El código resultante en esta parte del archivo debería parecerse a esto:

...
Kirigami.Page {
    title: i18n("develop.kde.org tutorial")

    Kirigami.Heading {
        anchors.centerIn: parent
        text: Backend.introductionText
    }

    actions {
        main: Kirigami.Action {
            ...
        }
    }
}

Ahora, vuelva a compilar el programa y ejecútelo.

¡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.