1
ESCOLA SUPERIOR ABERTA DO BRASIL – ESAB
GAMBAS: uma linguagem alternativa livre para desenvolvimento de aplicações GUI em
Linux
José Robson Araujo Silva1
Fábio Luiz Bigati2
Resumo
Este artigo visa a apresentar a linguagem GAMBAS, que é uma variante do BASIC, como
alternativa para desenvolvimento de aplicações com interface gráfica (GUI – Graphical User
Interface), em ambiente GNU/Linux, em oposição a linguagens comerciais mais conhecidas,
como Java e C/C++, as quais possuem curvas de aprendizagem bem mais íngremes. Para isso,
desenvolveu-se uma interface gráfica CRUD (Create/Read/Update/Delete) para o banco de
dados de demonstração livre, Chinook, em sua versão para SQLite. Concluiu-se, através deste
experimento, que a linguagem GAMBAS tem um grande potencial para o desenvolvimento de
aplicações do tipo front-end, pois além da facilidade no aprendizado, por ter uma ótima
documentação online e offline, embutida num bom ambiente integrado de desenvolvimento
(IDE), totalmente escrito em GAMBAS, com suporte a arrastar e soltar controles em uma
interface WYSIWYG (What You See Is What You Get), também apresenta suporte nativo aos
bancos de dados Postgres, MySQL, SQLite, além de suportar conexões via ODBC.
Palavras-chave: GAMBAS. BASIC. SQLite. GNU/Linux. Aplicações GUI.
1 Introdução
Diante da popularização crescente do sistema operacional GNU/Linux, cresce também
a demanda por aplicações e ferramentas de desenvolvimento, sobretudo, ferramentas que
possibilitem o desenvolvimento rápido de aplicações (RAD – Rapid Application
Development). Em razão deste cenário, o presente artigo objetiva a apresentar o projeto
Gambas como uma ferramenta alternativa às tradicionais para desenvolvimento de aplicações
com interface gráfica em ambiente GNU/Linux, com foco restrito a aplicações gráficas do
tipo front-end com acesso a banco de dados, delimitando assim o escopo deste trabalho. Com
1
2
Pós-graduando em MBA Profissional em Sistemas de Informação na Escola Superior Aberta do Brasil –
ESAB. ([email protected]).
Mestrando em Educação, Especialista em Novas Tecnologias da Educação, Bacharel em Sistemas de
Informação e Licenciado em Pedagogia.
2
vistas a atingir o objetivo proposto, apesar da escassez de material bibliográfico formal acerca
do tema, por tratar-se de um projeto alternativo em software livre, realizou-se uma pesquisa
bibliográfica em materiais disponíveis na internet, a qual subsidia a exposição descritiva do
tema, bem como realizou-se, complementarmente, o desenvolvimento de um projeto simples
dotado
de
uma
interface
gráfica
e
capaz
de
realizar
as
operações
CRUD
(Create/Read/Update/Delete) em um banco de dados SQLite, com o objetivo de experimentar
e demonstrar, na prática, o uso e a aplicação tanto da linguagem quanto do ambiente integrado
de desenvolvimento do Gambas na resolução do problema proposto, respeitando seu escopo e,
posteriormente, realizando uma análise qualitativa acerca da maturidade e usabilidade da
ferramenta em comento.
2 Desenvolvimento de aplicações GUI em GNU/Linux
O sistema operacional GNU/Linux, popularmente conhecido apenas como Linux, tem
aumentado cada vez mais sua participação em ambientes domésticos, organizações sem fins
lucrativos, empresas e órgãos governamentais. Entre os fatores responsáveis por esse aumento
estão a necessidade dos usuários de diminuir custos com licenças de software, aumentar a
segurança na rede, a busca por estabilidade, desempenho estável, economia de recursos de
hardware, facilidade na instalação de software, drivers de dispositivos e atualizações, bem
como acesso ao código-fonte, além de ter diversas opções de customização e poder escolher
entre múltiplos ambientes de área de trabalho como KDE, Gnome, Unity, Cinnamon, Mate,
XFCE, LXDE, entre outros (WIKIPÉDIA, 2015c).
Com o aumento da adoção do Linux, sobretudo em desktops e workstations, aumenta
também a demanda por aplicações para usuários finais, e com isso, surge a necessidade de
ferramentas que permitam o desenvolvimento prático e rápido de aplicações, não só para
consoles ou terminais (CLI – Command Line Interface), mas também, com interface gráfica
(GUI – Graphical User Interface). Porém, como explicitam Matthew e Stones (2007),
desenvolver aplicações gráficas em ambiente Linux não é uma tarefa simples, já que o suporte
a interfaces gráficas é proporcionado pelo X Window System (mais comumente chamado de
X11, ou apenas X), que por sua vez, ao contrário do que parece, não implementa nenhuma
interface gráfica, mas provê meios para que se possa implementar um ambiente gráfico
completo (desktop), através de sua estrutura composta por X Server, X Client (qualquer
3
aplicação para X), X Protocol e pela biblioteca Xlib, que por possuir uma API de nível muito
baixo, inviabiliza sua utilização direta para desenvolvimento de aplicações. Por esse motivo, é
necessário utilizar bibliotecas gráficas com API de nível mais alto (toolkits), que facilitam
sobremaneira o desenvolvimento, e dentre as quais, historicamente destacam-se as bibliotecas
Motif, OpenLook e Xt, bem como as mais modernas GTK+ e Qt. Note-se, também, que esta
abordagem genérica adotada pelo X Window System dificultou, por muito tempo, o
surgimento de ambientes desktop, tanto em Linux quanto em UNIX, até o surgimento de dois
projetos de desktops que ganharam enorme evidência entre os usuários de Linux: o GNOME e
o KDE, os quais foram construídos sobre as bibliotecas GTK+ e Qt, respectivamente.
Neste contexto, temos, como principais opções, dois toolkits com características bem
distintas. O GTK+ (GIMP Toolkit), escrito em linguagem C, e o Qt, escrito em linguagem
C++, sendo que ambos possuem suporte, tanto oficial quanto desenvolvido por terceiros, a
uma ampla variedade de linguagens de programação, como C, C++, Java, C#, Javascript,
Python, Ruby, entre outras. Uma terceira opção é desenvolver em Java, utilizando uma de
suas bibliotecas gráficas embutidas, AWT, SWING ou JavaFX. O problema em escolher uma
destas três linguagens e seus toolkits reside na demasiada e, em muitos casos, indesejada
complexidade destas ferramentas tradicionais, sendo que, até mesmo engenheiros de software
experientes podem demonstrar frustração com tal complexidade. Nesse sentido, Pike (2010)
afirma que, tendo a linguagem C e o UNIX tornado-se um padrão dominante em ambientes de
pesquisa, o desejo por uma linguagem de mais alto nível levou à criação do C++, o qual
trouxe uma implementação de orientação a objetos ao C, e mesmo sendo uma implementação
pobre, isto permitiu que o C++ se tornasse a linguagem preferencial escolhida por parte da
indústria e por muitas universidades pesquisadoras. Posteriormente, surgiu o Java, que era
como se fosse uma versão mais clara e enxuta do C++, e por volta do final dos anos 90, a
necessidade de uma linguagem para ensino, que fosse didática e que tivesse relevância, fez
com que o Java fosse escolhido para esse fim. Pike (2010) afirma, ainda, que estas linguagens
(C/C++ e Java), apesar de serem ótimas nas mãos de experts e funcionarem bem em grandes
projetos, são muito difíceis de usar, pois são difíceis de compreender, confusas e verbosas. E
que esta forma desajeitada, inerente às principais linguagens, causou uma certa reação,
favorecendo o surgimento de várias linguagens mais simples, como Ruby, Python, Lua,
Javascript, Erlang e outras, as quais tornaram-se populares e bem-sucedidas, em parte, como
uma rejeição às linguagens padrão.
4
Diante do cenário apresentado, a linguagem Gambas surge como uma opção bastante
adequada para pequenos projetos, pois apresenta características que favorecem sua adoção por
pessoas que possuem pouca ou nenhuma experiência no desenvolvimento de aplicações GUI
em Linux, já que mascara C, C++, X, GTK+ e Qt, estrutura sobre a qual ela é construída,
como será demonstrado adiante.
3 O projeto Gambas
A palavra Gambas é um acrônimo recursivo em inglês, Gambas Almost Means BASIC,
que significa, em tradução livre, “Gambas é quase BASIC”. A linguagem Gambas foi criada
por um programador francês, chamado Benoît Minisini (seu primeiro nome é pronunciado
[bənwa], em francês, segundo a Wikipédia (2015b)), em virtude de sua frustração com o
Microsoft Visual Basic, por causa da enorme quantidade de bugs e inconsistências que a
linguagem apresentava. Por ser um entusiasta da linguagem BASIC, Benoît Minisini
construiu o Gambas buscando aperfeiçoar a sintaxe do Visual Basic e implementando também
diversos recursos do ambiente integrado de desenvolvimento da Microsoft, pois Gambas além
de ser uma linguagem com total suporte à programação orientada a objetos, é também um
ambiente de desenvolvimento construído sobre um interpretador de BASIC e, além disso, é
um software livre, de código-fonte aberto, disponibilizado sob a licença GNU GPLv2 (GNU
General Public License, version 2), conforme definida pela Free Software Foundation (1991).
Quanto à sua arquitetura, Gambas é amplamente inspirado pelo Java, sendo assim, um
programa escrito em Gambas nada mais é do que um conjunto de arquivos, onde cada arquivo
representa uma classe que será compilada para ser executada posteriormente pelo
interpretador. A arquitetura do Gambas é composta basicamente por um compilador, um
interpretador, um arquivador, um componente GUI e um ambiente de desenvolvimento,
organizados como mostra a figura 1, a seguir:
5
Figura 1: Arquitetura do ambiente Gambas.
Fonte: Minisini (2015b)3.
A linguagem Gambas possui algumas características interessantes, elencadas por
Minisini (2015a), que a diferem de outras linguagens disponíveis e demonstram sua
versatilidade, tais como:
Cada projeto é armazenado em um único diretório e o arquivador transforma todo o
conteúdo do respectivo diretório em um único arquivo executável;
Recompilar um projeto requer apenas a compilação das classes que sofreram alguma
modificação e cada referência externa de uma classe é resolvida dinamicamente em tempo de
execução;
A arquitetura em componentes permite que a linguagem seja estendida com bastante
facilidade, já que qualquer um pode escrever componentes em forma de bibliotecas
compartilhadas que adicionam dinamicamente novas classes nativas ao interpretador, podendo
escrevê-las em C, C++ ou simplesmente em Gambas, contando com a documentação online e
com o código-fonte dos componentes originais;
Os projetos podem ser traduzidos facilmente para qualquer idioma, pois o Gambas foi
concebido com a internacionalização em mente e por isso tem suporte a strings (cadeias de
caracteres) codificadas no padrão UTF-8;
O modelo de objeto implementado é simples, mas é bastante poderoso.
O Gambas está em sua terceira versão, mais precisamente, na versão 3.7.1, e por ser
3
Projeto Gambas: arquitetura. Disponível em: <http://gambas.sourceforge.net/en/architecture.html>
Acesso em: 30 jun. 2015.
6
um projeto em desenvolvimento, apesar de completamente funcional e estável, ainda possui
componentes minimamente desenvolvidos ou inacabados, a exemplo do componente GTK+, e
outras desvantagens inerentes à forma como o projeto foi implementado, como a alta
dependência de bibliotecas de terceiros. Por isso, tendo sido desenvolvido originalmente para
ambiente Linux, Gambas está profundamente ligado ao padrão POSIX, bem como a várias
bibliotecas, entre as quais destacam-se: Qt4, Qt5, GTK+, SDL (Simple DirectMedia Layer),
Video4Linux, etc. Há ainda o problema da incompatibilidade entre projetos criados na
segunda versão e os criados na terceira versão do Gambas, pois houve aprimoramentos
significativos e substanciais, tanto na sintaxe da linguagem, quanto na estrutura do ambiente
de desenvolvimento, e por esse motivo, estão disponíveis para download no site do projeto
Gambas, tanto a segunda versão (2.24.0), quanto a terceira (3.7.1). Mas, apesar de estar em
desenvolvimento e ser mantido por uma pessoa apenas, não por uma empresa ou organização,
o projeto evolui com bastante agilidade, sendo que a penúltima versão (3.7.0) foi lançada em
14 de março de 2015, corrigindo 267 bugs reportados e adicionando 299 novas
funcionalidades, além de 7 otimizações, ao passo que a última versão (3.7.1) foi lançada em 1
de abril de 2015, menos de um mês depois, corrigindo todos os bugs reportados desde o
lançamento da versão anterior e trazendo mais funcionalidades, de acordo com Minisini
(2015b).
Quanto à compatibilidade, verifica-se que, devido à sua grande quantidade de
dependências, o projeto Gambas não é considerado multiplataforma, pois mesmo compilando
e instalando com pouca ou nenhuma dificuldade em diversas distribuições Linux diferentes,
há uma certa dificuldade em portar o código-fonte para outros sistemas operacionais, mesmo
para os mais populares, baseados em Unix, como aqueles derivados do BSD (FreeBSD,
OpenBSD, NetBSD), bem como o Solaris e o Mac OS X, além do Microsoft Windows, o qual
não é compatível em arquitetura nem com Linux nem com Unix/BSD. É possível observar os
níveis de compatibilidade do projeto Gambas com os principais sistemas operacionais no
quadro 1, abaixo:
Sistema Operacional
Nível de compatibilidade
Observação
Debian – Linux
OK
Ver arquivo README.DEBIAN no pacote de códigofonte.
Fedora – Linux
OK
-
Mandriva – Linux
OK
-
7
OpenSUSE – Linux
OK
-
RedHat – Linux
OK
Ver arquivo README.REDHAT no pacote de códigofonte.
Slackware – Linux
OK
Pode apresentar um pouco de dificuldade para compilar
ou instalar na versão 10.1 do Slackware.
Ubuntu – Linux
OK
Gambas 2 está disponível no repositório padrão do S.O.
Gambas 3 está disponível via repositório PPA.
FreeBSD
OK
Gambas 1 e 2 estão disponíveis oficialmente.
Gambas 3 pode ser compilado sem problemas.
OpenBSD
Incerto
Trabalho em progresso…
NetBSD
Incerto
Trabalho em progresso…
Mac OS X em PowerPC Ruim
É possível que compile normalmente, mas não
funcionará corretamente devido a bugs no
gerenciamento
de
terminação
(endianness
management)
Solaris
Incerto
Gambas compila normalmente, mas pode não funcionar
corretamente.
Windows
Ruim
As versões estáveis do compilador e do interpretador do
Gambas podem ser compilados através da ferramenta
CygWin, mas os componentes não podem. Desta
forma, é possível que aplicações sem interface gráfica
funcionem.
Quadro 1: Níveis de compatibilidade do projeto Gambas com diversos sistemas operacionais.
Fonte: Adaptado de Minisini (2015a)4.
Observando-se todas as características da linguagem apresentadas, nota-se que é
necessário um bom ambientes de desenvolvimento para que um programador possa usufruir
amplamente de todo o potencial encerrado na linguagem, e nesse quesito, o projeto Gambas
também não decepciona.
4 O ambiente integrado de desenvolvimento
O projeto Gambas contém, além da linguagem, um ambiente integrado de
desenvolvimento (IDE), cuja interface foi completamente desenvolvida na própria linguagem
Gambas, utilizando o componente de interfaces gráficas, ou seja, ao utilizar a interface do
IDE, o usuário recebe uma amostra do quão complexa pode ser uma aplicação desenvolvida
com tal ferramenta.
O ambiente integrado do Gambas foi criado com base no IDE do Microsoft Visual
Basic, sendo, portanto, muito semelhante a este. Ao executar o IDE do Gambas, visualiza-se
4
Documentação do Projeto Gambas: distribuições e sistemas operacionais. Disponível em:
<http://gambaswiki.org/wiki/doc/distro?w&l=en> Acesso em: 7 jul. 2015.
8
antes de tudo, a janela Tips of the day (Dicas do dia), a qual permite navegar por 30 dicas
muito úteis sobre a linguagem. Dispensada a dica do dia, nota-se que o IDE traz uma tela
inicial através da qual é possível criar novos projetos, abrir projetos existentes, abrir
aplicações de exemplo, gerenciar aplicações baixadas da Software Farm e acessar a Software
Farm (fazenda de aplicações), que é um repositório de aplicações desenvolvidas em Gambas.
Após a criação de um novo projeto ou abertura de um projeto criado anteriormente, verificase que a interface principal do IDE está dividido em seções e que cada uma delas tem uma
função específica dentro do ambiente para que o programador possa realizar diversas tarefas
inerentes ao desenvolvimento de software com facilidade e eficiência. Na lateral esquerda do
IDE existe uma seção, chamada de project explorer (explorador de projeto) que permite que o
programador possa pesquisar ou explorar a estrutura do projeto em uso – suas pastas,
arquivos, conexões de bancos de dados, etc. Na parte superior da lateral direita encontra-se a
properties window (janela de propriedades), a qual está dividida em duas abas, sendo que a
primeira aba permite a visualização e alteração das propriedades dos controles selecionados,
exibindo a descrição detalhada de cada propriedade destacada em sua porção inferior, ao
passo que a segunda aba permite observar e organizar a hierarquia dos controles presentes nos
forms (formulários). Abaixo da janela de propriedades está localizada a toolbox (caixa de
ferramentas) que, por sua vez, armazena todos os controles disponíveis para o programador,
organizados em diversas categorias (form, view, chooser, container, data, etc.), permitindo que
o programador encontre com facilidade, entre muitos, o controle desejado. Ao centro, na parte
inferior, quase como um rodapé, está acomodado o console, que é uma ferramenta bastante
versátil, na qual concentram-se todas as tarefas relativas a testes e detecção de erros (debug).
Esta ferramenta possui diversas abas através das quais o programador extrai da aplicação,
durante a execução em modo de debug (depuração), todas as informações necessárias para
correções de erros, podendo realizar várias tarefas como verificar na saída do console as
mensagens postas no código-fonte para controle, inspecionar variáveis, gerenciar breakpoints
(pontos de interrupção), controlar o fluxo da aplicação em teste, observar o stack backtrace
(controle da pilha), etc. O console possui ainda um avaliador de expressões. Por último, a
maior parte da porção central do IDE abriga uma seção reservada para que o programador
possa desenhar interfaces gráficas, chamadas de formulários (forms), bem como editar
documentos de texto de qualquer natureza, sejam eles classes, módulos, documentos HTML,
XML, CSS, etc. Esta seção permite que o programador possa abrir quantos formulários ou
9
classes e módulos julgar necessários, já que os organiza em abas especializadas e, sendo
assim, as abas que possibilitam a criação e edição formulários trazem funcionalidades
específicas para estas tarefas, bem como um editor de menus, ao passo que as abas que
comportam documentos de texto trazem funcionalidades voltadas para edição e navegação
pelo código-fonte, além de recursos mais avançados e complexos como highlight, que destaca
trechos do código-fonte e palavras reservadas da linguagem em cores diferentes definidas de
acordo com suas funções, e sugestões para completação do código digitado exibidas em
conjunto com a ajuda online em uma janela pop-up.
O IDE do Gambas proporciona ao programador a possibilidade de distribuir suas
aplicações em diversos formatos, já que além de poder executar a aplicação em modo de
depuração, o programador pode gerar, a partir de seu projeto, um único arquivo executável,
um arquivo compactado contendo todos os arquivos do projeto ou um pacote de instalação,
sendo que neste último caso, há opção de gerar pacotes (.rpm, .deb, etc.) para diversas
distribuições Linux disponíveis atualmente como Archlinux, Debian, Mageia, OpenSUSE,
Ubuntu / Mint, Fedora / RedHat / CentOS, Mandriva e Slackware, podendo ainda gerar
arquivos para instalação através da ferramenta Autotools.
Diante das características apresentadas, pode-se observar que o ambiente integrado de
desenvolvimento que acompanha a linguagem Gambas é, sem sombra de dúvida, uma
ferramenta extraordinária, como também elogia Nicholson (2011, p. 3). Resta agora verificar
na prática se é possível desenvolver aplicações úteis e funcionais utilizando-se tal ferramenta
e linguagem, e com que grau de facilidade ou de dificuldade consegue-se concluir esta tarefa.
5 Desenvolvendo uma aplicação simples
Desenvolveu-se para a produção deste artigo, como um test drive do ambiente
integrado de desenvolvimento e da linguagem BASIC presentes no projeto Gambas, uma
aplicação simples que consiste numa interface gráfica para um banco de dados de teste
chamado Chinook Database, que é uma alternativa livre ao banco de dados de exemplo
disponibilizado pela Microsoft em conjunto com seus produtos Access e SQL Server,
chamado Northwind Traders Database, que contém dados das transações de uma empresa
fictícia homônima, do ramo de importação e exportação de alimentos. O banco de dados
Chinook, cujo modelo é apresentado na figura 2, contém, por sua vez, dados fictícios de uma
10
loja que venderia músicas em meio digital para download, organizados em onze tabelas,
sendo que aqueles referentes ao acervo foram importados de uma biblioteca real (ROCHA,
2012).
Figura 2: Modelo de dados, ou esquema, do banco Chinook.
Fonte: Rocha (2012)5.
A aplicação desenvolvida, intitulada “Chinook CRUD” para referência, permite ao
usuário final, como o título sugere, a realização das quatro operações básicas no banco de
dados Chinook, quais sejam: criar, ler, atualizar e excluir (CRUD – Create / Read / Update /
Delete). Com foco no projeto Gambas, e não no banco de dados em si, optou-se pela versão
para SQLite da base de dados Chinook, pois o SQLite é um motor de banco de dados SQL
(structured query language) transacional, autossuficiente, sem servidor, e sem necessidade de
configuração ou instalação, além de ser um software em ampla utilização no mundo inteiro e
5
Documentação do projeto Chinook: esquema. Disponível em:
<https://chinookdatabase.codeplex.com/wikipage?title=Chinook_Schema> Acesso em: 21 jul. 2015.
11
cujo código-fonte é de domínio público (Kreibich, 2010), características que contribuem para
um ambiente de desenvolvimento mais simples e ágil, em oposição aos sistemas de
gerenciamento de bancos de dados (SGBD) mais robustos MySQL e Postgres ambos também
suportados pelos drivers nativos do projeto Gambas.
Apesar de a linguagem Gambas permitir a criação de controles como botões e caixas
de texto em tempo de execução, a interface, ou front-end Chinook CRUD foi totalmente
desenhada no editor de formulários do IDE, sem a necessidade de se escrever uma única linha
de código-fonte, através de recursos gráficos como “arrastar e soltar” usando o mouse e
posicionando os controles no formulário utilizando as teclas de seta, com o objetivo de
experimentar as comodidades que o Gambas proporciona ao programador que possui pouca
ou nenhuma experiência com esta ferramenta, e o resultado apresentou-se de forma bastante
satisfatória, como se pode constatar na figura 3, abaixo. Esta interface foi construída de forma
bastante simples e ágil, aproveitando-se a eficiência e praticidade do editor de formulários, e
utilizando-se um conjunto reduzido de controles, como é possível notar, já que foram
utilizados apenas: cinco botões (buttons) que permitem carregar ou limpar os dados exibidos
em cada aba, inserir novos registros, excluir registros existentes e salvar ou cancelar as
alterações realizadas; uma caixa de marcação (checkbox) para alternar entre o modo de
visualização e leitura dos registros e o modo que possibilita a edição dos mesmos; um divisor
em abas (tabstrip) responsável por separar cada tabela do banco de dados em uma aba
diferente; onze visualizadores de tabela (tableviews) que foram posicionados um a um nas
abas do divisor e têm a capacidade de exibir os registros carregados do banco de dados; além
de uma caixa de texto (textbox) que fica oculta ao usuário, sendo exibida somente no
momento da edição dos dados. Estes controles, além de terem sido organizados conforme
apresentados na figura 3, utilizando-se o editor de formulários, também tiveram algumas de
suas propriedades modificadas em relação a seus valores padronizados, através da janela de
propriedades, pois esta abordagem previne a inserção de linhas de código desnecessárias,
deixando o código-fonte mais simples, limpo e fácil de compreender. Apesar de a linguagem
permitir que o programador altere as propriedades dos controles em tempo de execução, de
forma programática, tal abordagem é melhor aproveitada nas ocasiões em que se deseja que
estas alterações ocorram de forma condicional, durante a execução e uso da aplicação e não
quando a intenção é apenas definir valores estáticos iniciais para estas propriedades. Desta
forma, para reproduzir corretamente a interface exibida na figura 3, é necessário observar
12
também, as informações apresentadas no Apêndice A, intitulado “Propriedades dos controles
no formulário FPrincipal”.
Figura 3: Interface Chinook CRUD exibindo registros carregados do banco de dados Chinook em SQLite.
Fonte: Elaboração própria (2015).
Após desenhada a interface e configuradas as propriedades de seus controles,
desenvolveu-se o código-fonte da aplicação Chinook CRUD, apresentado nos Apêndices B, C
e D. Como o IDE do Gambas trata de forma diferenciada os formulários (gráficos) e seus
códigos-fonte (textos), cada formulário criado gera automaticamente no projeto uma classe
homônima vinculada a este, através da qual é possível referenciar diretamente o respectivo
formulário, bem como seus controles, como sendo objetos, acessando assim suas propriedades
ou invocando seus métodos. Na pasta do projeto Chinook CRUD, por exemplo, o arquivo
“FPrincipal.form” representa o formulário em si, que é apenas um elemento visual estático,
conforme visto na figura 3, acima, enquanto que o arquivo “FPrincipal.class” representa uma
classe que encerra a lógica de programação responsável pela automação do formulário, ou
13
seja, contém o código-fonte que faz com que, por exemplo, o botão “Salvar” grave
efetivamente as alterações realizadas no banco de dados. Dito isto, entende-se que, já que o
projeto em questão possui apenas um formulário, toda a lógica estaria armazenada no arquivo
“FPrincipal.class”, cujo conteúdo está reproduzido integralmente no Apêndice B, nomeado de
“Código-fonte da classe FPrincipal”, porém, apesar de tal abordagem ser possível, devido à
heterogeneidade do código-fonte como um todo, em nome da legibilidade e da facilidade de
compreensão do mesmo, optou-se por seccioná-lo, mantendo na classe associada ao
formulário apenas a lógica referente ao próprio formulário, seus controles, propriedades,
ações e eventos, migrando-se o restante do código-fonte para outros dois arquivos.
O primeiro deles é “CDados.class”, que contém tanto a lógica de acesso ao banco de
dados quanto das operações CRUD, e seu teor pode ser observado detalhadamente no
Apêndice C, rotulado como “Código-fonte da classe CDados”. Esta classe acessa o arquivo
“Chinook.sqlite”, que contém o banco de dados e o representa, dependendo para tal tarefa,
tanto do sistema operacional, quanto do sistema de arquivos e até mesmo do hardware em si,
mais especificamente, do disco rígido (hard disk ou hard drive). Por este motivo, sua lógica
tem maior probabilidade de falhar, já que a aplicação pode não conseguir acessar o banco de
dados pelos mais diversos motivos, como falta de permissão, erro do sistema operacional,
inexistência do arquivo no disco, e mesmo que seja possível acessar o arquivo e realizar a
conexão, a lógica ainda pode falhar se alguma operação CRUD solicitada ao banco de dados
falhar ou for impossível de ser realizada, a exemplo da inserção de uma data inválida como
“31/02/2015”. Tendo em mente a possibilidade de falha, a classe CDados foi implementada
utilizando-se, em parte, o controle de erros que a linguagem proporciona através das palavras
reservadas try, catch e finally, sendo necessário observar, ainda, que a linguagem também
permite o controle de erros através do uso de rótulos (labels) em conjunto com as palavras
reservadas “On Error Goto” e “On Error GoSub”.
O segundo arquivo é “MBiblio.module” que contém toda a lógica reaproveitável e não
associada ao banco de dados nem ao formulário e seus elementos especificamente. Note-se
que este aquivo não representa uma classe, mas sim um módulo, que em Gambas é como uma
biblioteca, ou seja, contém funções que podem ser reutilizadas, evitando assim que haja
repetição de um mesmo trecho de código dentro do projeto, favorecendo a tarefa de
manutenção do código-fonte. O Apêndice D – Código-fonte do módulo MBiblio – traz esta
lógica, permitindo uma melhor compreensão da abordagem em comento.
14
Por fim, entende-se desnecessária a criação de um menu, que pode ser criado com
extrema facilidade utilizando-se o editor de menus disponível no IDE do Gambas, por ser o
Chinook CRUD uma aplicação simples, que não implementa qualquer tipo de funcionalidade
ou configuração avançadas. Cumpre-se assim o escopo proposto, qual seja, a implementação,
em Gambas, de uma interface gráfica capaz de realizar as operações CRUD no banco de
dados Chinook em SQLite. Note-se, no entanto, que esta aplicação pode ser aperfeiçoada,
pois ainda restam arestas que não foram aparadas, intencionalmente, em respeito ao prazo e
ao escopo propostos.
6 Conclusão
Após a implementação bem-sucedida do projeto Chinook CRUD pelo autor, mesmo
sem que este possuísse domínio prévio sobre a ferramenta (IDE do Gambas) ou sobre a
linguagem (Gambas BASIC), concluiu-se que o projeto Gambas cumpre seu papel, sem a
menor sombra de dúvida, permitindo que um usuário mediano do sistema operacional
GNU/Linux, não necessariamente um programador formado, possa desenvolver aplicações
simples, sobretudo interfaces do tipo front-end, com bastante facilidade e poucos
contratempos, já que Gambas é um dialeto BASIC e herda deste suas principais características
(ser fácil, de uso geral, extensível, interativo, amigável, veloz na execução, transparente e
seguro (MARCONI, 2015; WIKIPÉDIA, 2015a)). Usuários avançados de suítes de escritório
como Microsoft Office ou LibreOffice acostumados a escrever macros, para automatizar
planilhas por exemplo, não terão dificuldade em desenvolver pequenos projetos em Gambas,
já que ambas as suítes citadas adotaram implementações da linguagem BASIC para
automatização via macros cujos dialetos diferem minimamente daquele implementado por
Benoît Minisini.
Este artigo não pretende ser e, por consequência, não é um manual didático da
linguagem Gambas BASIC, mas pretende, no entanto, apresentar as características do projeto
como um todo, mantendo o foco na linguagem, no ambiente integrado de desenvolvimento e
no escopo das aplicações do tipo front-end com acesso a banco de dados. Mesmo assim, os
Apêndices B, C e D possibilitam um vislumbre da sintaxe da linguagem e de como funciona
sua lógica. Este artigo pretende, ainda, contribuir de forma significativa para a popularização
do Projeto Gambas e da filosofia do software livre, pois, apesar do escopo limitado deste
15
trabalho, o Gambas é muito mais versátil do que isto, podendo ser utilizado para desenvolver
aplicações de linha de comando, aplicações web (CGI), jogos e até mesmo scripts não
compilados, o que, sem dúvida, proporciona um ambiente rico e inspirador para trabalhos
vindouros, especialmente nas áreas de desenvolvimento web e de criação de jogos para
GNU/Linux utilizando a biblioteca SDL (Simple DirectMedia Layer).
Abstract
This article aims to present the GAMBAS language, which is a variant of BASIC, as an
alternative for developing graphical user interface (GUI) applications, on GNU/Linux
environment, as opposed to well-known commercial languages, like Java and C/C++, those of
which have more steep learning curves. For that purpose, a graphical CRUD
(Create/Read/Update/Delete) interface for the free demonstration database Chinook, in its
version for SQLite, was developed. It was concluded, through this experiment, that the
GAMBAS language has a great potencial for the development of applications of the front-end
type, for besides of its easiness of learning, for having a great online and offline
documentation, built in a good integrated development environment (IDE), totally written in
GAMBAS, with support to drag and drop controls in a WYSIWYG (What You See Is What
You Get) interface, it also brings native support to Postgres, MySQL and SQLite databases,
plus support to ODBC connections.
Keywords
GAMBAS. BASIC. SQLite. GNU/Linux. GUI Applications.
Referências
FREE SOFTWARE FOUNDATION. GNU General Public License, version 2. Boston: Free
Software Foundation Inc., 1991. Disponível em: <http://www.gnu.org/licenses/oldlicenses/gpl-2.0.html> Acesso em: 30 jun. 2015.
KREIBICH, J. A. Using SQLite: Small. Fast. Reliable. Choose Any Three. 1. ed. O'Rilley
Media, 2010.
MARCONI, A. M. History of BASIC: History of the BASIC Programming Language by
Andrea M. Marconi. Disponível em: <http://q7basic.org/History%20of%20BASIC.pdf>
Acesso em: 28 ago. 2015.
MATTHEW, N.; STONES, R. Beginning Linux® Programming 4th Edition. 4. ed. Wrox
Press e Wiley Publishing, 2007.
16
MINISINI, B. Documentação do Projeto Gambas. Disponível em:
<http://gambaswiki.org/wiki/doc/intro> Acesso em: 3 jul. 2015.
______. Projeto Gambas. Disponível em: <http://gambas.sourceforge.net/en/main.html>
Acesso em: 30 jun. 2015.
PIKE, R. Public Static Void. In: O'Reilly Open Source Convention (OSCON), 12, 2010,
Portland. Disponível em: <http://www.oscon.com/oscon2010> Acesso em: 26 jun. 2015.
ROCHA, L. Projeto Chinook Database. Califórnia: CodePlex (Microsoft), 2012. Disponível
em: <https://chinookdatabase.codeplex.com> Acesso em: 20 jul. 2015.
RITTINGHOUSE, J. W.; NICHOLSON, J. A Beginner's Guide to Gambas – Revised
Edition. 2. ed. Infinity Publishing, 2011. Disponível em:
<http://whiteislandsoftware.com/index.php?page=cedi&type=misc&id=64> Acesso em: 19
jul. 2015.
WIKIPÉDIA. BASIC. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia
Foundation, 2015. Disponível em: <https://pt.wikipedia.org/wiki/BASIC> Acesso em: 26 jul.
2015.
______. Benoît. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia Foundation,
2015. Disponível em: <https://en.wikipedia.org/wiki/Beno%C3%AEt> Acesso em: 30 jun.
2015.
______. Linux adoption. In: WIKIPÉDIA, a enciclopédia livre. Flórida: Wikimedia
Foundation, 2015. Disponível em: <https://en.wikipedia.org/wiki/Linux_adoption> Acesso
em: 26 jun. 2015.
17
APÊNDICE A – Propriedades dos controles no formulário FPrincipal
Nome do controle Tipo do controle
btnCarregar
btnInserir
btnExcluir
btnSalvar
btnCancelar
chkEditar
Button
Button
Button
Button
Button
CheckBox
Nome da propriedade
Valor da propriedade
Height
32
Text
Carregar Dados
Width
120
X
16
Y
8
Enabled
False
Height
32
Text
Inserir Linha
Width
120
X
211
Y
8
Enabled
False
Height
32
Text
Excluir Linha
Width
120
X
344
Y
8
Enabled
False
Height
32
Text
Salvar
Width
120
X
16
Y
392
Enabled
False
Height
32
Text
Cancelar
Width
120
X
144
Y
392
Enabled
False
18
Nome do controle Tipo do controle
chkEditar
txtEditor
tabTabelas
TableView1
a
TableView11
CheckBox
TextBox
TabStrip
TableViews
Nome da propriedade
Valor da propriedade
Height
24
Text
Editar
Width
70
X
139
Y
13
Height
32
Visible
False
Width
120
X
272
Y
392
Count
11
Height
328
Tag
Chinook
Album / Artist /
Customer / Employee /
Text (Obs.: cada aba tem Genre / Invoice /
sua propriedade Text.)
InvoiceLine / MediaType
/ PlayList / PlaylistTrack
/ Track
Width
496
X
16
Y
56
Group
TableViews
Header
Horizontal
Height
264
Mode
Single
Width
464
X
16
Y
24
19
APÊNDICE B – Código-fonte da classe FPrincipal
' Gambas class file
Static Private estaTableView As TableView
Static Private intSequencia As Integer
Public Sub _new()
End
Public Sub Form_Open()
CDados.Preparar()
End
Public Sub btnCarregar_Click()
MBiblio.DesCarregar(tabTabelas)
End
Public Sub tabTabelas_Click()
If btnSalvar.Enabled = True And tabTabelas.Index <> btnSalvar.Tag Then
tabTabelas.Index = btnSalvar.Tag
Message("Há dados não salvos nesta aba!")
Return
Endif
estaTableView = tabTabelas.Children[0]
btnCarregar.Text = IIf(Right(tabTabelas.Caption) = "*", "Limpar Dados", "Carregar Dados")
chkEditar.Enabled = Right(tabTabelas.Caption) = "*"
btnInserir.Enabled = Right(tabTabelas.Caption) = "*"
btnExcluir.Enabled = Right(tabTabelas.Caption) = "*"
If Right(tabTabelas.Caption) <> "*" Then
chkEditar.Value = False
btnSalvar.Enabled = False
btnCancelar.Enabled = False
Endif
If chkEditar.Value Then
btnInserir.Enabled = False
20
btnExcluir.Enabled = False
Endif
End
Public Sub chkEditar_Click()
If chkEditar.Value Then
CDados.GerenciarTransacoes("Iniciar")
btnExcluir.Enabled = False
estaTableView.Tag = "Editando"
Else
CVariant(tabTabelas.Children[0]).Cancel()
btnInserir.Enabled = True
btnExcluir.Enabled = True
Endif
End
Public Sub TableViews_Click()
If chkEditar.Value And Last.Column <> 0 Then
btnSalvar.Tag = tabTabelas.Index
If Right(Last[Last.Row, 0].Text, 1) <> "*" Then
Last.EditWith(txtEditor)
Endif
Endif
End
Public Sub txtEditor_Change()
If txtEditor.Text <> estaTableView.Current.Text Then
btnSalvar.Enabled = True
btnCancelar.Enabled = True
Endif
End
Public Sub TableViews_Save(Row As Integer, Column As Integer, Value As String)
btnSalvar.Enabled = True
btnCancelar.Enabled = True
Last[Row, Column].Text = Value
21
If estaTableView.Tag = "Editando" Then
CDados.editarCelula(Left(tabTabelas.Caption, -1), Last.Columns[0].Title, Last[Row,
0].Text, Last.Columns[Column].Title, Value)
Endif
End
Public Sub btnInserir_Click()
CDados.GerenciarTransacoes("Iniciar")
TableViews_Insert()
End
Public Sub TableViews_Insert()
If intSequencia = 0 Then intSequencia =
CDados.IntObterSequencia(Left(tabTabelas.Caption, -1))
estaTableView = tabTabelas.Children[0]
btnSalvar.Tag = tabTabelas.Index
If chkEditar.Value = False Then chkEditar.Value = True
btnSalvar.Enabled = True
btnCancelar.Enabled = True
If estaTableView.Tag = "Inserindo" Then
estaTableView.Rows.Count += 1
estaTableView[estaTableView.Rows.Count - 1, 0].Text = intSequencia +
estaTableView.Rows.Count
estaTableView.MoveTo(estaTableView.Rows.Count - 1, 1)
Else
estaTableView.Tag = "Inserindo"
estaTableView.Clear()
estaTableView.Rows.Count = 1
estaTableView[estaTableView.Rows.Count - 1, 0].Text = intSequencia + 1
estaTableView.MoveTo(estaTableView.Rows.Count - 1, 1)
Endif
estaTableView.EditWith(txtEditor)
txtEditor.SetFocus()
End
22
Public Sub btnSalvar_Click()
Dim i As Integer
If txtEditor.Text <> estaTableView.Current.Text Then
estaTableView.Current.Text = txtEditor.Text
Endif
If estaTableView.Tag = "Editando" Then
CDados.editarCelula(Left(tabTabelas.Caption, -1), estaTableView.Columns[0].Title,
estaTableView[estaTableView.Row, 0].Text,
estaTableView.Columns[estaTableView.Column].Title, txtEditor.Text)
estaTableView.Tag = ""
Endif
If estaTableView.Tag = "Inserindo" And estaTableView.Rows.Count > 0 Then
For i = 0 To (estaTableView.Rows.Count - 1)
CDados.InserirRegistro(MBiblio.StrGerarInsert(Left(tabTabelas.Caption, -1),
estaTableView, i))
Next
estaTableView.Tag = ""
Endif
CDados.GerenciarTransacoes("Salvar")
btnSalvar.Enabled = False
btnCancelar.Enabled = False
intSequencia = CDados.IntObterSequencia(Left(tabTabelas.Caption, -1))
End
Public Sub txtEditor_Leave()
If txtEditor.Text <> estaTableView.Current.Text Then
estaTableView.Current.Text = txtEditor.Text
If estaTableView.Tag = "Editando" Then
CDados.editarCelula(Left(tabTabelas.Caption, -1), estaTableView.Columns[0].Title,
estaTableView[estaTableView.Row, 0].Text,
estaTableView.Columns[estaTableView.Column].Title, txtEditor.Text)
Endif
Endif
23
End
Public Sub btnCancelar_Click()
CDados.GerenciarTransacoes("Cancelar")
btnCarregar_Click()
btnSalvar.Enabled = False
btnCancelar.Enabled = False
btnInserir.Enabled = False
btnExcluir.Enabled = False
End
Public Sub btnExcluir_Click()
If Right(estaTableView[estaTableView.Row, 0].Text, 1) <> "*"
btnSalvar.Tag = tabTabelas.Index
CDados.GerenciarTransacoes("Iniciar")
CDados.ExcluirRegistro(Left(tabTabelas.Caption, -1), estaTableView.Columns[0].Title,
estaTableView[estaTableView.Row, 0].Text)
estaTableView[estaTableView.Row, 0].Text &= "*"
btnSalvar.Enabled = True
btnCancelar.Enabled = True
Endif
End
24
APÊNDICE C – Código-fonte da classe CDados
' Gambas class file
Private Const cstTipoBD As String = "sqlite"
Private Const cstNomeBD As String = "Chinook"
Static Private Con As New Connection
Static Private Res As Result
Static Private blnEmTransacao As Boolean
Static Public arrTabela As Variant
Static Public arrCampos As String[]
Static Public arrLarguraCampos As Integer[]
Static Public Sub Preparar()
Con.Type = cstTipoBD
Con.Host = Application.Path
Con.Name = cstNomeBD & "." & cstTipoBD
End
Static Public Sub Conectar()
If Not Con.Opened Then
Try Con.Open()
If Error Then
Message("Não foi possível conectar ao banco '" & Con.Name & "' em " & Con.Host &
".")
Quit
Endif
Endif
End
Static Public Sub Desconectar()
If Con.Opened Then
Try Con.Close()
If Error Then
Message("Erro ao fechar conexão com o banco.")
25
Quit
Endif
Endif
End
Static Public Sub ObterTabela(strTabela As String)
Dim i, j As Integer
Res = Con.Find(strTabela)
arrTabela = New Variant[Res.Count, Res.Fields.Count]
arrCampos = New String[Res.Fields.Count]
arrLarguraCampos = New Integer[Res.Fields.Count]
For i = 0 To (Res.Fields.Count - 1)
arrCampos[i] = Res.Fields[i].Name
arrLarguraCampos[i] = Res.Fields[i].Length
Next
For i = 0 To (Res.Count - 1)
For j = 0 To (Res.Fields.Count - 1)
arrTabela[i, j] = Res[arrCampos[j]]
Next
Res.MoveNext()
Next
End
Static Public Sub EditarCelula(strTabela As String, strColunaID As String, strValorID As
String, strColunaEditada As String, strNovoValor As String)
Res = Con.Edit(strTabela, strColunaID & " = &1", strValorID)
Res[strColunaEditada] = strNovoValor
Res.Update()
Catch
Message("Não foi possível atualizar o valor da coluna " & strColunaEditada & " para " &
strNovoValor & ".")
End
Static Public Sub InserirRegistro(strInsert As String)
Try Res = Con.Exec(strInsert)
26
If Error Then
Message("Não foi possível inserir registro.")
Endif
End
Static Public Sub ExcluirRegistro(strTabela As String, strColunaID As String, strValorID As
String)
Try Res = Con.Exec("DELETE FROM " & strTabela & " WHERE " & strColunaID & " = "
& strValorID)
If Error Then
Message("Não foi possível excluir o registro de " & strColunaID & " = " & strValorID & "
da tabela " & strTabela & ".")
Endif
End
Static Public Function IntObterSequencia(strTabela As String) As Integer
Res = Con.Find("sqlite_sequence", "Name = &1", strTabela)
Return Res["seq"]
End
Static Public Function GerenciarTransacoes(strAcao As String)
If strAcao = "Iniciar" And blnEmTransacao = False Then
blnEmTransacao = True
Try Con.Begin()
If Error Then
blnEmTransacao = False
Message("Não foi possível Iniciar a transação.")
Endif
Endif
If strAcao = "Salvar" And blnEmTransacao Then
blnEmTransacao = False
Try Con.Commit()
If Error Then
blnEmTransacao = True
Message("Não foi possível Salvar a transação.")
27
Endif
Endif
If strAcao = "Cancelar" And blnEmTransacao Then
blnEmTransacao = False
Try Con.Rollback()
If Error Then
blnEmTransacao = True
Message("Não foi possível Cancelar a transação.")
Endif
Endif
End
28
APÊNDICE D – Código-fonte do módulo MBiblio
' Gambas module file
Const LarguraFixa As Integer = 100
Public Sub DesCarregar(estaTabStrip As TabStrip)
Dim i, j As Integer
Dim estaTableView As TableView
estaTableView = estaTabStrip.Children[0]
If Right(estaTabStrip.Caption) <> "*" Then
CDados.Conectar()
CDados.obterTabela(estaTabStrip.Caption)
estaTableView.Columns.count = CDados.arrCampos.Count
For i = 0 To (CDados.arrCampos.Max)
estaTableView.Columns[i].text = CDados.arrCampos[i]
estaTableView.Columns[i].width = IIf(CDados.arrLarguraCampos[i] > 10,
CDados.arrLarguraCampos[i] + LarguraFixa * 1.5, LarguraFixa)
Next
estaTableView.Rows.Count = (CDados.arrTabela.Bounds[0])
For i = 0 To (CDados.arrTabela.Bounds[0] - 1)
For j = 0 To (CDados.arrTabela.Bounds[1] - 1)
estaTableView[i, j].Text = CDados.arrTabela[i, j]
Next
Next
Else
estaTableView.Clear()
estaTableView.Rows.Count = 0
estaTableView.Refresh()
CDados.Desconectar()
Endif
estaTabStrip.Caption = IIf(Right(estaTabStrip.Caption) = "*", Left(estaTabStrip.Caption, -1),
estaTabStrip.Caption & "*")
29
FPrincipal.tabTabelas_Click()
End
Public Function StrGerarInsert(strNomeTabela As String, estaTableView As TableView,
intLinha As Integer) As String
Dim i As Integer
Dim strRetorno As String
strRetorno = "INSERT INTO " & strNomeTabela & " ("
For i = 1 To (estaTableView.Columns.Count - 1)
strRetorno &= estaTableView.Columns[i].Text & ","
Next
strRetorno = Left(strRetorno, -1)
strRetorno &= ") VALUES ("
For i = 1 To (estaTableView.Columns.Count - 1)
strRetorno &= "'" & estaTableView[intLinha, i].Text & "',"
Next
strRetorno = Left(strRetorno, -1)
strRetorno &= ")"
Return strRetorno
End
Download

ESCOLA SUPERIOR ABERTA DO BRASIL – ESAB GAMBAS: uma