Conecte um backend para fazer cálculos e fornecer à sua interface de usuário dados para exibir
Para integrar a lógica ao aplicativo, precisamos de classes de backend em C++ que possam realizar os cálculos importantes. Escrever lógica nos arquivos QML é desencorajado, portanto, tente migrar o máximo possível para o backend, de forma que o QML seja usado apenas para exibir a interface do usuário.
Primeiro, crie o arquivo de cabeçalho que terá o código exposto ao QML, ou seja, o 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);};
Há duas coisas necessárias para expor o código C++ ao QML, e uma delas é simplesmente usar a macro QML_ELEMENT, disponível no cabeçalho <QtQml/qqmlregistration.h>.
O backend será criado como um singleton, o que significa que ele será criado apenas uma vez e existirá durante toda a duração da aplicação. Para isso, usamos a macro QML_SINGLETON.
src/components/backend.cpp
Podemos adicionar nosso código inicial para o construtor ao arquivo backend.cpp:
A partir de agora, o backend será conhecido pelo QML como o tipo QML Backend. Ele está contido em um módulo chamado org.kde.tutorial.components.
Isso significa que, simplesmente adicionando a importação em um arquivo QML, é possível usar o código exposto do C++:
importorg.kde.tutorial.components
Para começar do zero usando o código existente do aplicativo, crie um novo componente QML que contenha uma página em branco:
1
2
3
4
5
6
7
importorg.kde.kirigamiasKirigamiimportorg.kde.tutorial.componentsKirigami.Page{title:"Exposing to QML Tutorial"// ...
}
src/Main.qml
Para realmente mostrar a nova página, vamos criar uma opção de menu que envia a nova página para o aplicativo, apenas para que possamos testar o modelo mais 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
Por fim, adicione os arquivos backend.h, backend.cpp e ExposePage.qml recém-criados ao CMake:
Agora conectamos a classe que contém a lógica futura à aplicação, mas ela ainda não faz nada. Para mudar isso, vamos adicionar uma propriedade à classe. Propriedades são muito mais do que uma simples variável. Elas podem informar a IU sobre alterações para que ela possa atualizar as áreas corretas.
Logo abaixo da macro QML_SINGLETON, adicione uma nova Q_PROPERTY.
Pode parecer muito código para apenas ler e escrever código no backend. No entanto, uma análise mais aprofundada revela que ler a propriedade na interface do usuário já pode executar alguma lógica — o mesmo quando ela é escrita. Nesse caso, ele informará automaticamente o frontend e o backend sobre as alterações.
A leitura e a escrita são baseadas no conceito de funções getter e setter. Vá em frente e adicione um novo atributo privado à sua classe que contenha os dados, bem como as funções getter e setter relevantes.
Adicione uma nova seção privada com o seguinte conteúdo:
A primeira função é o getter, a segunda o setter e a terceira um sinal que é emitido quando a propriedade é alterada. Elas correspondem às partes READ, WRITE e NOTIFY do Q_PROPERTY acima.
O resultado deverá ser semelhante ao seguinte:
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
O sinal não precisa de nenhuma implementação no arquivo backend.cpp, pois não faz muito mais do que ser emitido, mas o getter e o setter precisam ser implementados de forma semelhante ao seguinte:
Como você pode ver, quando o setter é chamado, o sinal será emitido e informará a interface do usuário e o backend sobre a alteração.
src/components/ExposePage.qml
Para exibir o texto, adicione um Kirigami.Heading em src/components/ExposePage.qml na propriedade title do componente Kirigami.Page que adicionamos ao código.
O código resultante nessa parte do arquivo deve ficar assim:
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}}
Agora compile e inicie seu programa novamente. Você verá que a nova página tem um título centralizado dizendo "Olá Mundo!".
Parabéns, você aprendeu:
Como registrar tipos de backend no QML
Adicionar novos elementos ao arquivo QML
Criar novas subclasses de QObject
Como adicionar propriedades e o que elas fazem
O que são sinais
Se você quiser saber mais sobre a integração entre QML e C++, recomendamos a leitura da documentação oficial do Qt.