Manual
do
Maker
.
com
Programo em Qt há vários anos já, mas nunca foquei em interface gráfica para mobile. Bem, desde alguns poucos artigos atrás estou expondo minhas novas experiências e ainda estou longe de dominar QML e Quick, mas percebi que seu eu não começar a escrever a respeito, vou perder meus estudos. Desse modo, coloco aqui os primeiros passos com QML que servirão a mim mesmo até que eu o domine e de quebra pode eventualmente ajudar outras pessoas.
Ao abrir o QtCreator, siga o menu File > New File or Project. À esquerda, em projects, o primeiro item é Application. Na coluna do centro tem as opções de projeto de aplicação, de onde selecionei como base o Qt Quick Application - Swipe. Foi a partir desse exemplo que escrevi o programa apresentado nesse outro artigo. Alguns recursos que precisei testar me obrigaram a mudar o core da aplicação, mas de qualquer modo é sempre bom partir de um exemplo do que sair do zero quando se está aprendendo.
Normalmente um projeto em Qt inicia com uma QMainWindow. Achei bastante estranho ter apenas um main.cpp e os arquivos QML. Classes criadas posteriormente podem herdar do QObject sem problemas.
Basicamente, o arquivo main.cpp tem uma instância do QQmlApplicationEngine ou uma outra opção que não me recordo agora (e essa é uma das razões pela qual resolvi anotar tudo). Não precisamos nos preocupar com isso, é a estrutura padrão inicial, mas estou citando para saber o que normalmente é encontrado no main.cpp.
Arquivos QML podem ser inclusos do sistema de arquivos, URLs externas ou como um recurso. Após carregado, o restante acontece conforme a programação. Por exemplo, posso fazer toda a interface no QML com Quick ou posso fazer em C++ e usar QML e Quick apenas para interagir com o C++. Em qualquer um dos casos, não utilizamos o QWidgets.
Já mostrei em vídeos no nosso canal DobitaobyteBrasil no Youtube como criar algumas aplicações com Qt, inclusive como fazer uma boa diagramação dos widgets. Para programar em Qt com QML e Quick utiliza-se o padrão MVC (Model, View, Controller). Não se apegue a design patterns por enquanto, vamos focar em "encaixar as engrenagens em seus eixos para entender o movimento do motor". Lembre-se que esses são apenas os primeiros passos com QML.
Quando cria-se um projeto em QML, se tiver forms de UI, ao clicar nele abrir-se-á o design com os componentes para elaboração da interface. Dependendo do que for incluído no projeto, o número de componentes variará.
Realmente não gosto de java script, mas não tem como fugir se pretende fazer interfaces interativas fluidas. O mínimo do mínimo será necessário, ainda que faça todo o backend em C++.
Na interface tem os componentes do QML, do Quick, Quick Controls (se estiver incluso no projeto), Posicionadores, views etc. Arrastando-os para o Form Editor fica fácil ajustar o design e incluir o código deles automaticamente sem precisar decorar de cara sua estrutura. Após isso, as implementações devem ser feitas clicando em Text Editor, sem sair do design. Resumindo:
Utilizando como base esse projeto swipe, o arquivo main.qml deve conter uma estrutura com conceitos importantes - e é por esse motivo que penso ser bom utilizar exemplos da própria IDE para começar, pois mesmo não reconhecendo a função de algumas implementações, elas passam a ficar claras conforme o projeto inicial vai evoluindo.
A ApplicationWindow é uma das maneiras de desenhar a janela da aplicação. Poderia ser composta sobre um retângulo, utilizando Rectangle invés dela, mas existem implicações, as quais serão citadas em outros artigos.
Basicamente, o modelo inicial composto na criação do projeto fica mais ou menos assim:
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
id: appWin
visible: true
width: 240
height: 240
title: qsTr("Tabs")
Rectangle {
id: teste
width: 240
height: 240
color: "blue"
}
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
Page1Form {
id: external
Timer {
interval: 2000
running: true
repeat: false
onTriggered: external.grabToImage(function (result){
if (!result.saveToFile("teste.png")){
console.error("Unknown error saving to");
}
result.close();
});
//onTriggered: console.error('timeout ok');
}
}
Page2Form {
}
}
footer: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
TabButton {
text: qsTr("Page 1")
}
TabButton {
text: qsTr("Page 2")
}
}
}
Já dei uma mexida nesse código, mas só algumas poucas linhas, porque estou criando um app pra rodar no display SPI apresentado nesse artigo.
Não vou falar dos imports agora porque quero citar também que existem versões diferentes e, no meu caso, para compilar no Raspberry com uma versão um pouco menos recente do Qt, tive que mudar a versão desses imports, que é o número adiante deles. Veremos mais em outro artigo.
A estrutura acima é hierárquica; ApplicationWindow > PageForm1 > Timer é um exemplo de multinível. Mas nesse exemplo em específico tem algo muito importante, que citarei em outro artigo também. Agora será apenas a apresentação.
Nesse mesmo exemplo também tem a execução de um timer e uma função, que devo entrar em detalhes no decorrer dos artigos posteriores.
Não estou interessado em escrever um livro nesse artigo, só estou fazendo a introdução mesmo, depois aprofundarei cada vez mais. Só para ter uma ideia, vou citar algumas propriedades utilizadas. Se não é habituado à linguagem orientada a objetos, as propriedades são elementos que dão características a um componente (ou objeto), podendo (ou não) ser um elemento visual. No caso de um retângulo (esse sim, um elemento visual), suas propriedades podem ser cor, borda, tamanho, nome de identificação e um extra bem específico que veremos em outro artigo - o nome de objeto, para ser invocado a partir do código C++ do projeto, caso desejado.
Coloquei um retângulo no código acima para servir de exemplo. No caso:
Rectangle {
id: teste
width: 240
height: 240
color: "blue"
}
Assim, quando abrir a janela da aplicação, haverá um retângulo azul de 240x240 px, com um id chamado "teste" (sem aspas).
É muito importante estar se referenciando sempre à documentação. Tendo os conceitos, bastará buscar as referências. No caso dos tipos, a documentação do QML é essa. É uma vastidão de tipos, a documentação é sua amiga!
O swipeViewé o recurso que nos permite ter o efeito de transição de página. Como o modelo inicial tem 2 páginas, elas são "importadas" dentro desse elemento. E isso que é interessante; manipular componentes de outros arquivos QML a partir do arquivo QML principal é fácil, além de ser a única maneira de executar funções para um PageForm.ui, que explicarei também em outro artigo.
Para começar, uma outra boa referência (além da documentação) é esse tutorial QML. Foi meu primeiro passo. Um pouco de animação visual, "alias" e manipulação de atributos são mostrados, o que abre horizontes! A didática é espetacular!
Agora estou de saída, mas deixo essa introdução para darmos continuidade em breve. Até a próxima!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.