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.

Dodaj następującą treść do pliku nowego nagłówka (tego z rozszerzeniem .h):

#pragma once

#include <QObject>

class Backend : public QObject
{
    Q_OBJECT

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

Plik cpp zawierający definicje jest podobnie pusty w tej chwili, powinien on zawierać coś na kształt:

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

Do main.cpp, zaraz po stworzeniu QQmlApplicationEngine, dodaj rejestrację typu w następujący sposób:

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

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

Od teraz, część logiczna będzie znana QML jako Backend. Zawiera się w module o nazwie org.kde.example. Ponieważ moduł jest częścią aplikacji, to nie musisz się martwić jego wersjonowaniem, wystarczy, że pozostaniesz przy 1.0 i będziesz jej używał przez całą aplikację.

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.

Zaraz pod makrem Q_OBJECT, dodaj nowe Q_PROPERTY.

Q_PROPERTY(QString introductionText READ introductionText WRITE setIntroductionText NOTIFY introductionTextChanged)

Wydaje się to całkiem dużo jak na prostą właściwość, której użyjemy do pokazania jakiegoś tekstu z części logiki programu, prawda? Po bliższym zapoznaniu, okazuje się, że może to odczytywać logikę, gdy właściwość jest czytana przez interfejs użytkownika oraz wtedy gdy jest zapisywania. Samoczynnie powiadomi część obsługi oraz logiki programu o zmianach.

Odczyt i zapis jest oparty na funkcjach getter oraz setter, więc dodaj nowy prywatny atrybut do twojej klasy, w ten sposób oraz dodaj funkcje getter oraz setter.

private:
    QString m_introductionText = "Hello World!";

Do działu publicznego, dodaj

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

Pierwsza funkcja to pobieracz, druga to ustawiacz, a trzecia to sygnał wysyłany gdy właściwość ulegnie zmianie. Sygnał nie potrzebuje żadnej implementacji w pliku cpp, bo nie robi nic więcej poza byciem wysłanym, lecz pobiercze i ustawiacze muszą być zaimplementowane w sposób podobny do poniższego:

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.

Aby wyświetlić tekst, dodaj w main.qml nagłówek, wyświetlający go zaraz pod właściwością tekstową rzeczy Kirigami.Page, która znajduje się już w tym szablonie

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.