Neste texto gostaria de exemplificar a construção de um pequeno aplicativo no melhor estilo hello world (Olá Mundo).
OBS: Caso eu tenha criado o tópico no lugar errado, algum moderado favor direcionar para o local correto .
Resolvi escrever sobre o tema devido a uma das perguntas aqui do fórum:
Qual a vantagem de usar Flatpak?
A ideia é apenas mostrar um outro ponto de vista para o crescimento do Flatpak.
O qual acredito que não seja apenas pelo isolamento da aplicação (e outras vantagens e desvantagens discutidas no link acima), mais sim pelo conjunto de ferramentas que o Gnome tem disponibilizado para o desenvolvimento de aplicativos.
Digo isso porque independente da linguagem de programação sempre chegamos em um ponto onde a criação de binários, o empacotamento e distribuição se tornam problemáticos.
Para este texto meio tutorial serão utilizadas as seguintes ferramentas:
Gnome Builder
O GNOME Builder é um ambiente de desenvolvimento integrado (IDE) com foco no desenvolvimento de aplicativos para o ecossistema do Gnome.
Ele irá fornecer uma estrutura de projeto padronizada e é nele que iremos desenvolver a lógica do aplicativo.
Acredito que em algum momento o designe da interface será encorporado a ele.
Até o momento em que escrevo é possível trabalhar com as linguagens:
C#
.C
.C++
.JavaScript
.Python
.Vala
.
A instalação do Gnome Builder pode ser realizada via repositório (apt
, dnf
, yay
, etc) das distribuições Linux.
Exemplo: sudo apt install gnome-builder
No entanto para utilizar as versões mais recentes ou mesmo a versão de desenvolvimento é recomendada a instalação via Flatpak.
- Gnome Builder no FlatHub.
- Pagina oficial do Gnome Builder.
Glade
O Glade é uma ferramenta que permite a criação de interfaces gráficas de forma visual.
O grande beneficio dessa prática é poder separar o designe da interface, da lógica de programação.
Essa interface gerada pelo Glade pode ser utilizada juntamente com a linguagem Python através da Classe Gtk.Builder()
ou pelo decorador @GtkTemplate()
do Gnome Builder.
A instalação do Glade pode ser feita também via repositório (apt
, dnf
, yay
, etc) das distribuições Linux.
Exemplo: sudo apt install glade
Sua instalação também pode ser feita utilizando-se Flatpak.
- Glade no FlatHub.
- Pagina oficial do Glade.
Neste caso acredito que não existam grandes diferenças entre a versão do repositório e o Flatpak, a menos que se esteja utilizando uma distribuição mais antiga ou com foco em estabilidade.
Iniciando o desenvolvimento
Para iniciar o projeto vamos abrir o Gnome Builder, na tela inicial podemos contribuir com algum projeto ou mesmo acessar estes projetos para estudo, no entanto queremos iniciar um novo projeto para isso basta clicar em Novo:
Na tela seguinte podemos configurar o projeto definindo:
- Nome do projeto.
- Local do projeto.
- Linguagem que será utilizada (Python neste caso).
- Licença do projeto.
- Se será utilizado controle de versão (git).
- Modelo do projeto (Selecione Aplicativo do GNOME).
Após realizar as configurações basta clicar em Criar:
O Gnome Builder será iniciado e vai começar a baixar os SDKs (runtimes) necessários para o desenvolvimento do aplicativo:
Com o fim do download podemos iniciar o desenvolvimento.
Vamos começar executando o projeto que já temos, para isso bastar pressionar Ctrl + F5
ou clicar no botão que parece um play na barra de cabeçalho (antiga barra de titulo):
Como resultado temos uma janela com o texto Hello, World!, essa janela é exibida porque escolhemos um modelo do Gnome como base para o projeto.
Podemos fechar a janela que foi exibida e começar o desenvolvimento.
Do lado esquerdo do IDE temos a estrutura de diretórios que foi criada para o projeto, o que nos interessa neste momento é a pasta src
e os arquivos:
window.py
: Arquivo/Script Python onde criaremos a lógica do aplicativo.window.ui
: Arquivo do tipoXML
que descreve a interface do aplicativo.
Vamos começar pelo arquivo window.ui
o mesmo deve ser aberto com o Glade para que possamos alterá-lo de forma visual:
Ao abrir o arquivo vemos a mesma janela que foi exibida ao se executar o projeto no Gnome Builder.
A ideia é fazer uma janela que tenha:
- Um widget do tipo label.
- um widget do tipo entry.
- um widget do tipo botão.
Importante notar que cada widget tem um campo chamado
ID
e este campo deve ser único, isso porque este nome será utilizado como nome de variável no Python!
Caso não queira tentar desenhar a interface da imagem acima utilize o seguinte XML
:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="HelloWorldWindow" parent="GtkApplicationWindow">
<property name="can_focus">False</property>
<property name="default_width">600</property>
<property name="default_height">300</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title">Olá Mundo</property>
<property name="show_close_button">True</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkEntry" id="entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="placeholder_text" translatable="yes">Digite algo</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Este texto será alterado!</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button">
<property name="label" translatable="yes">Clique Aqui</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
</template>
</interface>
Para utilizar este
XML
basta acessar o arquivowindow.ui
do Gnome Builder e colar o conteúdo.
Com a interface criada podemos abrir o arquivo window.py
do Gnome Builder e começar a desenvolver a lógica.
A ideia é pegar o valor digitado no entry
e exibir no label
quando o button
for clicado, se o entry
estiver vazio exibimos outra mensagem.
Para executar a proposta um código possível é:
# window.py
#
# Copyright 2019 Renato Cruz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from gi.repository import Gtk
from .gi_composites import GtkTemplate
# Decorador que faz a leitura do arquivo ``window.ui``.
@GtkTemplate(ui='/org/gnome/Hello-World/window.ui')
class HelloWorldWindow(Gtk.ApplicationWindow):
"""Classe."""
__gtype_name__ = 'HelloWorldWindow'
# Atribuindo os widgets da interface nas variáveis.
# A ID (XML) deve ser o mesmo da variável.
entry = GtkTemplate.Child()
label = GtkTemplate.Child()
button = GtkTemplate.Child()
def __init__(self, **kwargs):
"""Construtor/inicializador."""
super().__init__(**kwargs)
self.init_template()
# Conectando o sinal (signal) clicked ao slot (ação).
# Quando o botão é clicado o método _on_button_clicked() é executado.
self.button.connect('clicked', self._on_button_clicked)
def _on_button_clicked(self, button):
"""Método é chamado quando o botão da interface é clicado.
:param button: Instância do objeto ``Gtk.Button`` que foi pressionado.
"""
# Verificando se algum valor foi digitado no entry.
if self.entry.get_text():
# Alterando o texto do label para o valor digitado no entry.
self.label.set_label(self.entry.get_text())
# Se nenhum valor for digitado no entry é exibida uma mensagem no label.
else:
self.label.set_label('Digite algo no campo acima!')
Perceba que a solução apresenta acima não é a única possibilidade, todavia foi a que eu considerei mais simples.
Ao executar este código (Ctrl + F5
) temos como resultado:
Temos o aplicativo sendo executado e realizado a proposta, agora vamos ver como empacotar e ver o que o Gnome Builder resolve neste aspecto.
Empacotamento
Se não estivéssemos utilizando o Gnome Builder eu teria que começar a utilizar/testar ferramentas como:
- Cx_Freeze.
- PyInstaller.
- py2exe.
- Nuitka.
- Etc.
E claro na hora de empacotar (deb, rpm, etc) verificar:
- Se as dependências do Python estão sendo copiadas e compiladas de forma correta.
- Se o tema, ícones e bibliotecas do Gnome estão sendo copiadas.
- Entre outros cuidados e detalhes.
Vale notar que mesmo com esses cuidados pode haver uma diferença visual entre o que foi criado e o que é executado. Isso porque cada ambiente gráfico utiliza um
CSS
e diretórios diferentes para criar o estilo da interface.
Bom pra mim é aqui que o Gnome Builder se destaca, isso porque ele realizada uma abstração de todas essas etapas, claro temos que notar que nosso aplicativo é simples e não possui dependências externas.
Para empacotar e distribuir o aplicativos vamos na barra de cabeçalho do Gnome Builder e vamos clicar na opção exportar:
Ao final do processo basta verifcar o diretório onde o aplicativo foi salvo.
Este diretório costurma ser /home/SeuUsuário/.var/app/org.gnome.Builder/cache/gnome-builder/projects/hello-world/flatpak/staging/x86_64-sem versão/
, mas podem haver variações. Na duvida basta ver o final do log que foi gerado no terminal.
Ao acessar o diretório percemos que o formato final é um Flatpak! Sim o Gnome apoia esse formato e reparem que da forma com que está já é possível distribuir o aplicativo, basta dar 2 cliques sobre o arquivo org.gnome.Hello-World.flatpak
.
Gnome Software:
KDE Discover:
Com o final da instalação basta procurar o aplicativo no menu da distribuição que se está utilizando.
Com isso finalizamos o nosso aplicativo e realmente tenho que eloginar o trabalho que o projeto Gnome está fazendo com o Gnome Builder.
Em poucos passo conseguimos empacotar e distribuir nosso aplicativo de exemplo.
Conclusão
Eu sei que para o usuário pode ser custoso fazer downloads grandes, problemas com espaço em disco e tudo mais, porém acredito que por muitos anos o mais custoso e doloso foi desenvolver um aplicativo e ter que escolher em qual distribuição o mesmo será executado e até mesmo a fragmentação que é gerada.
Por isso em um primeiro momento não acho critico ou mesmo impeditivo o tamanho do download em vista da praticidade que é gerada (lado do dev).
Claro, cabe analisar que o formato Flatpak está apenas começando e tanto Gnome, KDE e Freedesktop ainda estão se adaptando a este novo formato de empacotamente, acredito inclusive que em alguns anos teremos runtimes bem mais otimizadas .
Caso encontre algum erro favor entrar em contato para que o conteudo possa ser atualizado . Espero não ter me perdido muito no texto, Valeu!