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

Aby zaszyć logikę w aplikacji, potrzebujemy klas logiki programu, które będą mogły wykonywać ważne obliczenia. Odradzamy pisanie logiki w plikach QML, więc spróbuj przenieść tyle ile się da do logiki programu tak, aby QML był używany tylko do interfejsu użytkownika, w czym jest najlepszy.

Dla nowej klasy backend, utwórz dwa nowe pliki o nazwie backend.cpp oraz backend.h. Nie zapomnij dodać nowego pliku cpp do pliku wykonywalnego w src/CMakeLists.txt, obok main.cpp.

Add the following content to the new header file (backend.h):

#pragma once

#include <QObject>

class Backend : public QObject
{
    Q_OBJECT

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

The backend.cpp file containing the definitions is similarly empty right now, it should contain something like the following:

#include "backend.h"

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

}

Obecnie, interfejs użytkownika nie wie o twojej klasie z logiki programu. Aby to zmienić, musimy zarejestrować nowy rodzaj w main.cpp. Logika programu zostanie utworzona jako singleton, co oznacza, że zostanie utworzona tylko raz i będzie istnieć przez cały czas od otwarcia do zamknięcia programu.

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);

Nie zapomnij dołączyć pliku nowego nagłówka na górze main.cpp.

From now on, the backend will be known to QML as Backend. It is contained in a module called org.kde.example. Since the module is part of the application, you don't need to worry about versioning it, just stay with 1.0 and use it consistently throughout the application.

W main.qml, zaimportuj nowy moduł:

import org.kde.example 1.0

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 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!";

Do działu publicznego, dodaj

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();
}

Jak widzisz, gdy setter jest wywoływany, to sygnał zostanie wysłany i powiadomi interfejs oraz silnik o zmianie.

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

Kod wynikowy w tej części pliku powinien wyglądać następująco:

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

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

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

Teraz skompiluj i uruchom twój program ponownie.

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

Jeśli chcesz dowiedzieć się więcej o integracji pomiędzy QML oraz C++, zlecamy przeczytanie oficjalnej dokumentacji Qt.