Você está na página 1de 17

Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.

php/Mantendo_A_Sanidade_Com_O_Glade

Mantendo A Sanidade Com O Glade


From CInLUG

Conteúdo
1 Introdução
2 Interfaces em XML
3 GTK+ & Glade
3.1 Glade 3
3.1.1 Obtendo e Instalando
3.1.2 Componentes da Interface do Glade 3
4 Programação Orientada a Eventos
4.1 Eventos, Sinais e Callbacks
4.1.1 Sinais
4.1.2 Callbacks
4.2 Explodindo Coisas
5 Usando o Glade 3
5.1 Criando a Interface
5.1.1 Propriedades
5.1.2 Container Widgets
5.1.3 Empacotamento
5.1.4 Callbacks
5.1.5 Arquivo .glade
5.1.6 Referências
6 Libglade
6.1 Python
6.1.1 Código
6.1.2 GladeXML
6.1.3 Executando
6.2 C
6.2.1 Código
6.2.2 Compilando & Executando
6.3 C++
6.3.1 Código
6.3.2 Compilando & Executando
6.4 Java
6.4.1 Código
6.4.2 Compilando & Executando
6.5 C#
6.5.1 Código
6.5.2 Compilando & Executando
6.6 Ruby
6.6.1 Código
6.6.2 Executando
6.7 Haskell
6.7.1 Código
6.7.2 Compilando & Executando
7 DevHelp

Introdução
No RPG Call of Cthulhu (http://en.wikipedia.org/wiki/Call_of_Cthulhu_%28role-playing_game%29) , os personagens dos jogadores perdem pontos
de sanidade sempre que entram em contato com os "horrores que o homem não deveria saber que existem". Na vida real, programadores perdem
sanidade em vários momentos (na verdade, é raro algum atingir idade avançada e continuar bom da cabeça), e um desses contatos macabros é com o
desenvolvimento de interfaces com o usuários. Um outro é com processos de desenvolvimento como o RUP, mas vocês não estão aqui pra ouvir
isso. Vamos às interfaces com o usuário.

As GUIs não são essencialmente um problema, construí-las pode ser divertido para alguns: desenhar as telas que o usuário deve ver, a disposição
dos componentes, aparência geral, etecetera. O que não é nada divertido é passar o design pra código: escrever dezenas de comandos do tipo "criar

1 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

janela", "criar botão", "colocar botão dentro da janela", e por aí vai. Uma interface grande e complexa, como um processador de texto, pode ser um
pesadelo. E esta é sua primeira perda de sanidade! A solução para isso é utilizar algum Interface Designer, onde você pode realmente desenhar ou,
melhor dizendo, montar sua interface com os componentes (chamados widgets (http://pt.wikipedia.org/wiki/Widgets) ) disponíveis, como botões,
caixas de texto, e coisas do tipo. Depois de criada sua interface é gerado código com aqueles comandos simiescos "criar janela", "colocar botão". A
loucura começa quando você altera o código gerado, resolve que precisa mudar a interface, daí gera mais código. E as mudanças que você fez? Não
pode simplesmente copiar e colar, vai ter de escrever tudo de novo. E esta será sua segunda perda de sanidade!

Interfaces em XML
Uma prática comum em programação é dividir a aplicação a ser criada em camadas (http://en.wikipedia.org/wiki/Three_tier) , podemos ter uma
camada de dados, que cuida do acesso às informações em disco ou banco de dados, camada de negócio (ou camada lógica) que contém os
algoritmos aplicados aos dados provenientes do usuário, e este normalmente interage com o sistema via camada de apresentação - em nosso caso a
interface gráfica. Podemos "terceirizar" o trabalho de criação da interface gráfica para fora do código, guardando-a na forma de uma descrição em
XML, a ser carregada dinamicamente pela camada de apresentação de nossa aplicação, que deve conectar as ações do usuário sobre essa interface à
funções na camada de negócio.

Dessa forma, a descrição de nossa interface é mantida numa linguagem descritiva (XML), e deixamos a linguagem de programação para nossos
whiles e ifs. Uma solução bastante sã.

GTK+ & Glade


GTK+ é uma biblioteca para construção de interfaces gráficas com usuário, originária do projeto GIMP, escrita em C e licenciada sob a LGPL
(http://creativecommons.org/licenses/LGPL/2.1/deed.pt) , que permite seu uso para criação de softwares GPL e não-GPL. Ela também é multi-
plataforma (você pode programar para Windows e Linux numa tacada só) e, mesmo sendo escrita em C, é multi-linguagem (são muuuuitas
linguagens). Muito mais pode ser dito sobre GTK+, mas fica para outra oportunidade.

O XML usado para descrever a interface é o GladeXML, gerado através do construtor de interfaces Glade. Ele é carregado em tempo de
execução por nosso programa utilizando os serviços da libglade. Duas coisas muito boas resultarão dessa prática:

podemos alterar a interface sem alterar ou recompilar o código


podemos carregar a interface descrita pelo arquivo GladeXML de qualquer linguagem que possua bindings para biblioteca GTK+ e libglade:
C, C++, Java, Perl, Python, C#, Pike, Ruby, Haskell, Objective Caml, Scheme, Ada, Erlang, PHP, Pascal (alou, povo do Delphi, vocês podem
ser livres!), e várias outras.

E lembrem-se: não confundam "Glade", a aplicação de desenho de interface, com "libglade", a biblioteca que carrega as descrições de interface de
arquivos GladeXML, gerados pelo Glade. Entenderam?

Glade 3
Por muito tempo a versão estável do construtor Glade foi a 2, que possuía diversas limitações, até que em 11 de agosto, há quase duas semanas (e
estamos, eu e esse texto, em 2006, caso interesse), foi liberado o Glade 3.0 (http://glade.gnome.org/) , com as características que faltavam ao Glade
2. Por ser uma aplicação lançada recentemente, o pacote .deb para o Ubuntu, que usarei como base para os exemplos, não existe neste ponto do
continuum espaço-temporal. Será então necessário sujar as mãos baixando o código fonte e compilando, mas ora, esse é um artigo sobre
programação! Mesmo assim, caso não dê certo você pode acompanhar o artigo utilizando o Glade 2 mesmo, que no Debian/Ubuntu está nos pacotes
glade e glade-gnome. O segundo pacote se trata de uma versão do Glade 2 compilada com suporte a componentes de interface do GNOME. O que
me leva a falar de uma importante melhoria do Glade 3, que é a carga dinâmica de componentes para o construtor de interfaces. Basta disponibilizar
um arquivo catalog que descreve o novo widget, para ele ser adicionado ao Glade 3.

Obtendo e Instalando

A versão mais recente do Glade pode ser encontrada em http://ftp.gnome.org/pub/GNOME/sources/glade3/3.0/ Baixe o arquivo com a extensão
.tar.gz (ou .tar.bz2).

Para uma compilação bem sucedida vamos precisar de alguns pacotes, por isso repitam comigo:

$ sudo apt-get install build-essential libxml-parser-perl libgtk2.0-dev libxml2-dev

Então podemos começar. Visitem http://ftp.gnome.org/pub/GNOME/sources/glade3/3.0/ e troquem o X.Y da primeira linha abaixo para os valores da
versão mais recente.

2 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

$ wget http://ftp.gnome.org/pub/GNOME/sources/glade3/3.0/glade3-3.X.Y.tar.gz
$ tar -xvzf glade3-3.X.Y.tar.gz
$ cd glade3-3.X.Y
$ ./configure
$ make
$ sudo make install

Se tudo correr bem você encontrará uma entrada para o Glade no menu Aplicações->Programação.

Componentes da Interface do Glade 3

Na imagem acima, da esquerda para direita: Paleta, Janela Principal (o espaço vazio é, ou será, a Árvore de Widgets) e Editor de Propriedades.
Veremos como usar cada um depois, agora não daremos nem um passo sem um pouco de teoria, se não gosta, bem... você já compilou o Glade 3.0
mesmo, então pule para Usando o Glade 3. E cuidado com o Lado Negro!

Programação Orientada a Eventos


Esse não é exatamente mais um paradigma de programação, e sim uma necessidade técnica quando se está programando para um ambiente onde a
ação pode acontecer a qualquer momento vinda de qualquer lugar. Para ficar mais claro, lembra daquele programa que você fez quando estava
aprendendo sua primeira linguagem, aquele que perguntava a idade do sujeito e dizia alguma gracinha de acordo com a resposta? Naturalmente era
um programa que rodava na linha de comando, onde ele apresentava uma mensagem "Digite sua idade:" e essa pergunta bloqueava o fluxo do
computador - nada mais poderia ser feito até que ela fosse respondida ou o programa fosse interrompido. Por outro lado, o mesmo programa num
ambientes gráfico teria de lidar com questões bem mais complexas do que as do exemplo anterior, especialmente porque teria de dividir o espaço
com vários outros programas e não podia simplesmente bloquear todo sistema a espera de estímulos do usuário. Então usamos a técnica do Main
Loop, um laço "infinito" (ou while true, como dizem por aí) onde o programa fica inquirindo o sistema se tem algum evento para ele. Tem? Tem?
Tem? Tem?... Sem parar. Bem, não exatamente. O programador associa ações (funções, métodos) a determinados eventos, como o clique do mouse
sobre um botão, quando ocorre tal evendo, o fluxo do programa é desviado do Main Loop para a tal ação. E depois volta ao loop ou finaliza o
programa.

Eventos, Sinais e Callbacks


Como foi mencionado anteriormente, o usuário através dos dispositivos de entrada gera eventos, esperando com isso disparar algum comportamento
na aplicação. A figura abaixo mostra o caminho percorrido pelo estímulo do usuário até a consecução da função.

3 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Sinais

Quando os eventos (passando pelo GDK, que está abstraído na figura anterior) chegam ao Main Loop, este serve como uma espécie de comutador e
os repassa para os widgets relevantes. O widget é o ponto final da viagem do evento, que começou no dispositivo do usuário, e de acordo como o
widget foi programado, ele decidirá que sinais irá emitir. Cada widget possui uma lista de sinais' que pode emitir, como "clicked", "pressed",
"released", "change", etc, e é nesses sinais que as funções que o usuário deseja realizar são conectados. Chamamos estas funções conectadas à
sinais de widgets de callbacks.

Callbacks

Quando o evento chega do Main Loop para o widget, este procura os sinais relevantes a serem disparados e chama os callbacks conectados a estes
pelo programador. Seria algo como dizer ao widget: '"ei botão, se lhe acontecer de te clicarem, ligue para este número que eu tomo uma atitude".
Como ilustrado na figura anterior, os sinais não conectados não têm funções para chamar, fazendo com que o evento que o disparou "se perca".

Explodindo Coisas
A figura abaixo mostra a janela de uma aplicação num ambiente gráfico. Nada poderia ser mais simples...

...até explodirmos tudo.

4 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Vamos catar os pedaços:

1. Servidor X - responsável pelo controle do hardware gráfico, oferece abstração para aplicações gráficas. Recebe input de dispositivos do
usuários, como mouse e teclado, gerando eventos que são enviados para as aplicações.
2. Borda da Janela - colocada pelo gerenciador de janelas, que recebe os eventos de clique do mouse sobre o X e os repassa para a aplicação
que esta sendo emoldurada por ele.
3. Janela GDK - aqui entramos nas especificidades do toolkit gráfico GTK+, GDK (GIMP Drawning Kit) é uma camada de abstração sobre as
funções de desenho do Servidor X, que facilita a portabilidade de GTK+ para plataformas não-Linux, como Win32 ou MacOSX. A janela
GDK é do tamanho da área controlada por sua aplicação, ela recebe os eventos do Servidor X (XEvents), os transforma em GDKEvents e os
repassa dessa forma para GTK+.
4. Window Widget - componente de interface de alto nível, dentro da janela são dispostos os demais componentes. Como vimos até agora, a
"Janela" não inclui as bordas, que são provideciadas pelo Gerenciador de Janelas.
5. Demais Widgets - botões, entradas de texto, mais qualquer coisa que se possa empacotar numa janela.

O que vai nos interessar neste artigo está nos itens 4 e 5.

Usando o Glade 3
Agora vamos trabalhar, então abra o Glade. Você verá algo como o primeiro screenshot, mas para facilitar
nossa comunicação vamos mudar algo: vá na janela principal do Glade e clique no menu View->Palette
Appearance->Text beside icons. Sua paleta de widgets vai ficar como na figura ao lado.

Agora podemos começar.

Criando a Interface
Clique no botão "Window" na paleta, será adicionada uma janela ao seu projeto. Observe como as janelas
principal e de propriedades ficaram mais interessantes:

5 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

1. A janela recém criada onde colocaremos os outros widgets.


2. A entrada correspondente na árvore de widgets.
3. Propriedades dos widgets, onde iremos alterar suas características.

Propriedades

As propriedades sempre se referem ao widget em destaque, que pode ser escolhido clicando-se sobre ele na janela de edição, ou sobre seu nome na
árvore de widgets. Vamos ajustar as características da nossa janela mudando os valores na aba Geral, conforme a tabela abaixo:

Propriedade Novo Valor


Nome janelaPrincipal
Título da Janela Exemplo

E na aba Comum:

Propriedade Novo Valor


Pedido de Largura 300
Pedido de Altura 120

Neste ponto salve sua interface como simple.glade.

Container Widgets

O fundo de malha cinza em 1 na figura anterior significa um espaço vazio onde podemos
colocar um widget, fazendo do widget que possui o espaço vazio um container. Para colocar
vários precisamos utilizar widgets containers, que disponibilizam vários espaços vazios onde
podemos dispor os vários widgets da interface. Na paleta, selecione o widget Vertical Box
na seção Containers, o cursor deve tomar a forma do ícone associado com uma Vertical
Box, leve-o até a área cinza na janela que estamos editando e clique, aparecerá um diálogo
perguntando seu tamanho, escolha 2.

6 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

A linha horizontal no meio da janela é invisível e serve para indicar que são duas áreas
distintas, onde podemos incluir 2 widgets.

Agora adicionamos os dois últimos widgets do nosso exemplo: na seção Control and
Display escolha Combo Box para o espaço superior, e Label para inferior.

Mude suas propriedades na aba


Geral:

Combo Box
Propriedade Novo Valor
Nome combo
Pequeno
Items Normal
Grande

Label
Propriedade Novo Valor
Nome etiqueta
Etiqueta <small>Texto de exemplo.</small> "etiqueta" e "combo" são filhos de "vbox1", que por
Utilizar Markup Sim sua vez é filho de "aplicação"

Empacotamento

Quem já usou coisas como Delphi ou VisualBasic, mesmo depois dos danos ao poder de raciocínio, deve ter notado que ao construir interfaces os
widgets permaneciam exatamente onde foram colocados, e havia algo semelhante a uma "grade" para facilitar o posicionamento ordenado. Além
disso, uma vez pronta a aplicação, quando o usuário aumentava a janela, nada se movia e um vasto e anti-estético espaço não aproveitado surgia nas
extremidades. Ou então o usuário é proibido de redimensionar a janela, o que é uma truculência por parte do programador (a não ser que haja uma
boa razão). Toolkits gráficos modernos como GTK+ usam gerenciadores de layout para posicionar e dimensionar de forma inteligente os widgets
numa janela. As duas propriedades mais importantes para isso são

Expandir: se o widget container (pai) aumentar, este widget aumenta junto, ocupando o máximo de espaço possível, mas sem aumentar o
tamanho desenhado do widget.
Preencher: faz com que o widget ocupe visualmente todo espaço disponível.

Você pode imaginar que a combinação das duas propriedades de empacotamento acima podem resultar em widgets enormes. No glade temos acesso
às maravilhas do layout moderno através da aba Empacotamento da janela de Propriedades. Vamos alterar os nossos:

combo
Propriedade Novo Valor
Expandir Não
Preencher Sim

etiqueta
Propriedade Novo Valor
Expandir Sim
Preencher Sim

Experimente redimensionar e maximizar a janela e veja o que acontece com os widgets.

Callbacks

Agora vamos definir que queremos que o sinal "changed", na seção GtkComboBox da nossa Combo Box chamada combo, que é disparado toda
vez que o usuário escolher um item diferente em sua lista, seja conectado a um callback que chamaremos de "mudaTamanho"; e o sinal "delete-
event" (seção GtkWidget) da janelaPrincipal vamos dizer que deve ser conectado a uma callback chamado "sair".

7 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Arquivo .glade

Ao final teremos isto:

1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>


2. <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
3. <!-- Generated with glade3
4. Version: 3.0.0
5. Date: Tue Aug 29 00:19:15 2006
6. User: setanta
7. Host: poe
8. -->
9. <glade-interface>
10. <widget class="GtkWindow" id="janelaPrincipal">
11. <property name="width_request">300</property>
12. <property name="height_request">120</property>
13. <property name="title">Exemplo</property>
14. <signal name="delete_event" handler="sair"/>
15. <child>
16. <widget class="GtkVBox" id="vbox1">
17. <property name="visible">True</property>
18. <child>
19. <widget class="GtkComboBox" id="combo">
20. <property name="visible">True</property>
21. <property name="items" translatable="yes">Pequeno
22. Normal
23. Grande</property>
24. <signal name="changed" handler="mudaTamanho"/>
25. </widget>
26. <packing>
27. <property name="expand">False</property>
28. </packing>
29. </child>
30. <child>
31. <widget class="GtkLabel" id="etiqueta">
32. <property name="visible">True</property>
33. <property name="label" translatable="yes">&lt;small&gt;Texto de exemplo.&lt;/small&gt;</property>
34. <property name="use_markup">True</property>
35. </widget>
36. <packing>
37. <property name="position">1</property>
38. </packing>
39. </child>
40. </widget>
41. </child>
42. </widget>
43. </glade-interface>
44.

Referências

Informações valiosas sobre a aplicação Glade em:

http://glade.gnome.org/docs/index.html

Libglade
A libglade é reponsável por parsear o arquivo XML com a descrição da interface e criar os widgets correspondentes em tempo de execução e
conecta os sinais que definidos no glade aos callbacks implementados no código. A libglade está disponível nas linguagens em que GTK+ está
disponível, e no futuro será integrada no núcleo de GTK+, embora a libglade externa não seja eliminada, para manter a compatibilidade. A seguir a
interface definida no arquivo simple.glade será usada por diversas linguagens: Python, C, C++, Java, C# e Ruby. O código define que quando um
item for selecionado no combo box (valores "Pequeno", "Médio" e "Grande"), o tamanho do texto no label deve mudar de acordo. Tenha em mente
que é necessário obter referências, ou ponteiros, para os widgets se quisermos manipulá-los, e isso é obtido através da propriedade Name que
definimos para eles no Glade. Se tivermos o cuidado de não mudar o nome dos widgets e dos sinais, podemos mudar a interface a vontade sem

8 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

precisar mexer no código. As explicações estarão na forma de comentários no próprio código, e os exemplos em todas as linguagens deve ser o mais
semelhante possível entre si. Compare o procedimento de operação entre as diversas linguagens, você notará que as diferenças são mais devido à
linguagem do que a lógica de GTK+, embora isso fique mais claro em programas maiores do que o nosso exemplo.

Daqui para frente, um zoológico de linguagens. Escolha sua preferida, se cansar dela, escolha outra, a lógica de GTK+ será a mesma.

Python
Em minha humilde opinião, Python é uma das linguagens mais legais para se programar, boa para aprender coisas novas e com bastante suporte de
vários projetos de software livre, então começaremos por ela.

Veja mais em:

http://www.pygtk.org
http://www.pygtk.org/pygtk2reference/index.html
http://www.async.com.br/faq/pygtk/index.py?req=all (Recomendado!)
http://www.pythonbrasil.com.br/moin.cgi/PyGtk

Código

1. #!/usr/bin/python
2. #Arquivo: simple.py
3.
4. import pygtk
5. pygtk.require("2.0")
6. import gtk, gtk.glade
7.
8. class Aplicacao:
9. def __init__(self):
10. #Carrega a interface a partir do arquivo glade
11. arvoreDeWidgets = gtk.glade.XML('simple.glade')
12.
13. #Associa os widgets a variaveis;
14. #Os widgets que sao obtidos a partir de pedidos ao objeto 'arvoreDeWidgets'
15. self.janela = arvoreDeWidgets.get_widget('janelaPrincipal')
16. self.etiqueta = arvoreDeWidgets.get_widget('etiqueta')
17. self.combo = arvoreDeWidgets.get_widget('combo')
18.
19. #Conecta Sinais aos Callbacks
20. arvoreDeWidgets.signal_autoconnect(self)
21.
22. #Define o valor padrao dentre os itens da lista combo box
23. self.combo.set_active(0)
24.
25. #Exibe toda interface
26. self.janela.show_all()
27.
28. #Inicia o loop principal de eventos (GTK MainLoop)
29. gtk.main()
30.
31. #Callbacks
32.
33. def mudaTamanho(self, widget):
34. if widget.get_active_text() == 'Pequeno':
35. self.etiqueta.set_markup('<small>Texto de exemplo.</small>')
36. elif widget.get_active_text() == 'Normal':
37. self.etiqueta.set_markup('Texto de exemplo.')
38. elif widget.get_active_text() == 'Grande':
39. self.etiqueta.set_markup('<big>Texto de exemplo.</big>')
40.
41. def sair(self, widget, data):
42. #Sai do loop principal de eventos, finalizando o programa
43. gtk.main_quit()
44.
45. #Inicia a aplicacao
46. if __name__ == "__main__":
47. Aplicacao()
48.

GladeXML

O método gtk.glade.XML (e seus correlatos nas outras linguagens) retorna um objeto do tipo GladeXML, que guarda uma árvore de widgets
semelhante aquela mostrada na janela principal da aplicação Glade. A partir deste objeto podemos obter referências para todos diversos widgets, e
também podemos conectar os sinais às nossas funções callback com o método signal_connect. Em programas maiores utiliza-se o método
signal_autoconnect (http://www.pygtk.org/pygtk2reference/class-gladexml.html#method-gladexml--signal-autoconnect) , mas isso fica como lição de
casa. ;)

Executando

Pacotes Necessários

Python é um dos componentes mais importantes no desktop Linux, logo numa instalação padrão do Ubuntu e outras distribuições que usam o
GNOME como desktop, não será necessário instalar mais nada.

9 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Para rodar o programa basta conceder permissão de execução para o arquivo simple.py (via linha de comando com chmod ou clicando com o botão
direito no arquivo, em seguida clicando em Propriedades, daí vá na aba Permissões e habilite a opção Execução), então basta clicar duas vezes no
executável.

C
C foi escolhida como linguagem de desenvolvimento de GTK+ pela padronização da linguagem, portabilidade e uso
extensivo em projetos de software livre. Por estranho que pareça, a biblioteca GTK+ é totalmente orientada a objetos, num
modelo que lembra linguagens OO modernas como Java. Sim, dá um trabalhão, mas compensa, principalmente pela Pacotes
facilidade de fazer bindings para diversas linguagens de mais alto nível. Normalmente as aplicações são escritas nestas Necessários
linguagens. Veja mais em:

http://www.gtk.org libgtk2.0-dev
http://developer.gnome.org/doc/API/2.0/gtk/index.html libglade2-dev
http://developer.gnome.org/doc/API/libglade/libglade.html

Código

1. //Arquivo: simple.c
2. #include <gtk/gtk.h>
3. #include <glade/glade.h>
4.
5. //Widgets como variaveis globais
6. GtkWidget *janelaPrincipal, *combo, *etiqueta;
7.
8. //Callbacks
9. void
10. sair(GtkWidget *widget, GdkEventKey *e)
11. {
12. //Sai do loop principal de eventos, finalizando o programa
13. gtk_main_quit();
14. }
15.
16. void
17. mudaTamanho(GtkWidget *widget)
18. {
19. gchar* texto = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
20.
21. if (!g_ascii_strcasecmp(texto, "Pequeno")) {
22. gtk_label_set_markup(GTK_LABEL(etiqueta),
23. "<small>Texto de exemplo.</small>");
24. } else if (!g_ascii_strcasecmp(texto, "Normal")) {
25. gtk_label_set_markup(GTK_LABEL(etiqueta),
26. "Texto de exemplo.");
27. } else if (!g_ascii_strcasecmp(texto, "Grande")) {
28. gtk_label_set_markup(GTK_LABEL(etiqueta),
29. "<big>Texto de exemplo.</big>");
30. }
31. }
32.
33. //Inicia a aplicacao
34. int
35. main(int argc, char *argv[])
36. {
37. GladeXML *arvoreDeWidgets;
38.
39. gtk_init( &argc, &argv );
40.
41. //Carrega a interface a partir do arquivo glade
42. arvoreDeWidgets = glade_xml_new("simple.glade", NULL, NULL);
43.
44. //Associa os widgets a variaveis;
45. //Os widgets que sao obtidos a partir de pedidos ao objeto 'arvoreDeWidgets'
46. janelaPrincipal = glade_xml_get_widget(arvoreDeWidgets, "janelaPrincipal");
47. etiqueta = glade_xml_get_widget(arvoreDeWidgets, "etiqueta");
48. combo = glade_xml_get_widget(arvoreDeWidgets, "combo");
49.
50. //Conecta Sinais aos Callbacks
51. glade_xml_signal_autoconnect(arvoreDeWidgets);
52.
53. //Define o valor padrao dentre os itens da lista combo box
54. gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
55.
56. //Exibe toda interface
57. gtk_widget_show_all(janelaPrincipal);
58.
59. //Inicia o loop principal de eventos (GTK MainLoop)
60. gtk_main ();
61.
62. return 0;
63. }
64.

Compilando & Executando

$ gcc -o simplec simple.c `pkg-config --cflags --libs libglade-2.0 gtk+-2.0` -rdynamic


$ ./simplec

O flag -rdynamic do gcc usado no exemplo acima é necessário para o correto funcionamento da função glade_xml_signal_autoconnect, que verifica
a tabela de símbolos da aplicação em busca de funções com nomes idênticos aos callbacks definidos na aplicação Glade.

C++

10 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Algumas características da natureza da linguagem C++, como a falta de mecanismos de introspecção, nos impede de
usar a função signal_autoconnect da libglade. Assim, o código para C++ será um pouco diferente, o que pode ser
convertido numa vantagem, pois poderemos observar uma outra forma de conectar sinais e callbacks. Também há uma Pacotes
diferença na implementação do callback mudaTamanho: a opção escolhida na ComboBox é verificada Necessários
numericamente, em lugar de comparar Strings. Eu estava cansado e tive preguiça de manipular strings em C++, que não
é minha primeira linguagem de programação.
libgtkmm-2.4-dev
...... escreva algo sobre Gtk::Main::run(janela....); libglademm-2.4-dev

Veja mais em:

http://www.gtkmm.org
http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/index.html (Excelente!)
http://www.gtkmm.org/docs/gtkmm-2.4/docs

Código

1. //Arquivo: simple.h
2. #ifndef SIMPLE_H
3. #define SIMPLE_H
4.
5. #include <gtkmm.h>
6. #include <libglademm.h>
7.
8. class Aplicacao
9. {
10.
11. //Widgets
12. Gtk::Window *janelaPrincipal;
13. Gtk::ComboBox *combo;
14. Gtk::Label *etiqueta;
15.
16. public:
17. Aplicacao();
18.
19. //Callbacks
20. virtual void mudaTamanho();
21.
22. };
23.
24. #endif // SIMPLE_H
25.

11 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

1. //Arquivo: simple.cpp
2. #include "simple.h"
3.
4. Aplicacao::Aplicacao()
5. {
6. //Carrega a interface a partir do arquivo glade
7. Glib::RefPtr<Gnome::Glade::Xml> arvoreDeWidgets =
8. Gnome::Glade::Xml::create("simple.glade");
9.
10. //Associa os widgets a variaveis;
11. //Os widgets que sao obtidos a partir de pedidos ao objeto 'arvoreDeWidgets'
12. arvoreDeWidgets->get_widget("janelaPrincipal", Aplicacao::janelaPrincipal);
13. arvoreDeWidgets->get_widget("etiqueta", Aplicacao::etiqueta);
14. arvoreDeWidgets->get_widget("combo", Aplicacao::combo);
15.
16. //Conecta Sinais aos Callbacks
17. Aplicacao::combo->signal_changed().connect(
18. sigc::mem_fun(*this, &Aplicacao::mudaTamanho));
19.
20. //Define o valor padrao dentre os itens da lista combo box
21. Aplicacao::combo->set_active(0);
22.
23. //Exibe toda interface
24. Aplicacao::janelaPrincipal->show_all();
25.
26. Gtk::Main::run(*janelaPrincipal);
27. }
28.
29. //Callbacks
30. void
31. Aplicacao::mudaTamanho()
32. {
33. switch (this->combo->get_active_row_number())
34. {
35. case 0:
36. this->etiqueta->set_markup("<small>Texto de exemplo.</small>");
37. break;
38. case 1:
39. this->etiqueta->set_markup("Texto de exemplo.");
40. break;
41. case 2:
42. this->etiqueta->set_markup("<big>Texto de exemplo.</big>");
43. break;
44. default:
45. // Tem algo errado aqui
46. break;
47. }
48. }
49.
50. //Inicia a aplicacao
51. int
52. main(int argc, char* argv[])
53. {
54. Gtk::Main kit(argc, argv);
55. Aplicacao aplicacao;
56. return 0;
57. }
58.

Compilando & Executando

$ g++ simple.cpp -o simplecpp `pkg-config gtkmm-2.4 libglademm-2.4 --cflags --libs`


$ ./simplecpp

Java
O binding GTK+ para Java se chama Java-GNOME e no site do projeto pode ser encontrada uma documentação de
excelente qualidade, incluindo como compilar programas Java-GNOME para código nativo, usar com o Eclipse e mais
ainda. Este código difere um pouco dos demais, pois acrescentei alguns lançamentos de exceções, que me foram pedidas Pacotes
pelo compilador, além de ter do nome do arquivo ser obrigatoriamente o mesmo da classe pública, em nosso caso Necessários
Aplicacao.java. Perceba também que não é necessário conectar os sinais, basta criar métodos com os nomes dos callbacks
definidos no Glade, que Java-GNOME faz o trabalho do Autoconnect autoconectmaticamente. Se gosta da idéia de
programar com Java e GTK, dê olhada nesse Hello World (http://java-gnome.sourceforge.net/cgi-bin/bin/view libglib-java
/Main/JavaGnomeHelloWorld) , e em: libgtk-java
libglade-java
http://java-gnome.sourceforge.net
http://java-gnome.sourceforge.net/docs/GNOME-tutorial/index.html
http://java-gnome.sourceforge.net/docs/glade-tutorial/index.html
http://java-gnome.sourceforge.net/docs/javadoc/index.html
http://java-gnome.sourceforge.net/cgi-bin/bin/view/Main/EclipseDevelopment (como usar o Eclipse com Java-GNOME)
http://java-gnome.sourceforge.net/cgi-bin/bin/view/Main/SettingLDLibPath
http://java-gnome.sourceforge.net/cgi-bin/bin/view/Main/NativeBinaries
http://java-gnome.sourceforge.net/cgi-bin/bin/view/Main/UsingAMakefile

Código

12 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

1. //Arquivo: Aplicacao.java
2. import java.io.FileNotFoundException;
3. import java.io.IOException;
4.
5. import org.gnu.glade.LibGlade;
6. import org.gnu.glade.GladeXMLException;
7. import org.gnu.gtk.Gtk;
8. import org.gnu.gtk.Widget;
9. import org.gnu.gtk.Window;
10. import org.gnu.gtk.ComboBox;
11. import org.gnu.gtk.Label;
12.
13. public class Aplicacao
14. {
15. private Window janelaPrincipal;
16. private Label etiqueta;
17. private ComboBox combo;
18.
19. public Aplicacao() throws FileNotFoundException, GladeXMLException,
20. IOException
21. {
22. //Carrega a interface a partir do arquivo glade
23. LibGlade arvoreDeWidgets = new LibGlade("simple.glade", this);
24.
25. //Carrega os Widgets em variaveis
26. janelaPrincipal = (Window) arvoreDeWidgets.getWidget("janelaPrincipal");
27. etiqueta = (Label) arvoreDeWidgets.getWidget("etiqueta");
28. combo = (ComboBox) arvoreDeWidgets.getWidget("combo");
29.
30. //Define o valor padrao dentre os itens da lista combo box
31. combo.setActive(0);
32.
33. //Exibe toda interface
34. janelaPrincipal.showAll();
35.
36. //Inicia o loop principal de eventos
37. Gtk.main();
38. }
39.
40. //Callbacks
41.
42. public void mudaTamanho()
43. {
44. String text = combo.getActiveText();
45.
46. if (text.equals("Pequeno")) {
47. etiqueta.setMarkup("<small>Texto de exemplo</small>");
48. } else if (text.equals("Normal")) {
49. etiqueta.setMarkup("Texto de exemplo.");
50. } else if (text.equals("Grande")) {
51. etiqueta.setMarkup("<big>Texto de exemplo.</big>");
52. }
53. }
54.
55. public void sair()
56. {
57. //Sai do loop principal de eventos
58. Gtk.mainQuit();
59. //Finaliza o programa
60. System.exit(0);
61. }
62.
63. //Inicia a aplicacao
64. public static void main(String[] args)
65. {
66. try {
67. Gtk.init(args);
68. new Aplicacao();
69. Gtk.main();
70. } catch(Exception e) {
71. e.printStackTrace();
72. }
73. }
74. }
75.

Compilando & Executando

$ javac -classpath /usr/share/java/glade2.12.jar:/usr/share/java/gtk2.8.jar:/usr/share/java/glib0.2.jar Aplicacao.java


$ java -classpath .:/usr/share/java/glade2.12.jar:/usr/share/java/gtk2.8.jar:/usr/share/java/glib0.2.jar Aplicacao

C#
Agora uma seção que deixará as mocinhas que tudo que vem da Micro$oft é do mal: GtkSharp! <Meu Disclaimer>
Crianças vocês podem chamar de "do mal" todas as coisas que vierem deles que possam te prender, limitar sua escolha ou
colocar seus traseiros e a sociedade nas mãos deles. O resto não tem problema. Vocês não adoram RTF? Foram eles que Pacotes
inventaram. </Meu Disclaimer> Voltando aos negócios, não tenho muita experiência com C#, mas como disse um professor Necessários
lá do CIn "quem sabe Java, num fim de semana aprende C#". Daí extrapolando, quem sabe Java e GTK+, em menos de 1
hora faz um programinha em GtkSharp, ou melhor, GladeSharp. Uma das coisas legais que notei é que o Autoconnect da
libglade não só conecta os sinais, mas também os widgets à atributos definidos como WidgetProperties. Ah, syntatical mono-mcs
suggar! Vejam o código pra saber do que falo. Se quiser também pode experimentar o MonoDevelop libgtk2.0-cil
(http://monodevelop.com/Main_Page) . libglade2.0-cil

Mais informações em:

13 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

http://www.mono-project.com/GtkSharp
http://www.mono-project.com/GtkSharpBeginnersGuide
http://www.go-mono.com/docs/index.aspx?link=N:Glade
http://www.mono-project.com/Guide:Running_Mono_Applications

Código

1. //Arquivo: simple.cs
2. using System;
3. using Gtk;
4. using Glade;
5.
6. public class Aplicacao
7. {
8. //A linha a seguir faz com que o widget abaixo dela seja automaticamente
9. //conectado ao widget de mesmo nome no arquivo glade
10. [Glade.WidgetAttribute]
11. Gtk.Window janelaPrincipal;
12. [Glade.WidgetAttribute]
13. Gtk.Label etiqueta;
14. [Glade.WidgetAttribute]
15. Gtk.ComboBox combo;
16.
17. public Aplicacao(string[] args)
18. {
19. Application.Init();
20.
21. //Carrega a interface a partir do arquivo glade
22. Glade.XML arvoreDeWidgets = new Glade.XML(null, "simple.glade", null, null);
23.
24. //Associa os widgets a variaveis e conecta os Sinais aos Callbacks
25. arvoreDeWidgets.Autoconnect(this);
26.
27. //Define o valor padrao dentre os itens da lista combo box
28. combo.Active = 0;
29.
30. //Exibe toda interface
31. janelaPrincipal.ShowAll();
32.
33. //Inicia o loop principal de eventos (GTK MainLoop)
34. Application.Run();
35. }
36.
37. //Callbacks
38.
39. public void mudaTamanho(object obj, EventArgs args) {
40. String text = ((Gtk.ComboBox) obj).ActiveText;
41.
42. if (text == "Pequeno") {
43. etiqueta.Markup = "<small>Texto de exemplo.</small>";
44. } else if (text == "Normal") {
45. etiqueta.Markup = "Texto de exemplo.";
46. } else if (text == "Grande") {
47. etiqueta.Markup = "<big>Texto de exemplo.</big>";
48. }
49. }
50.
51. public void sair(object obj, DeleteEventArgs args) {
52. //Sai do loop principal de eventos, finalizando o programa
53. Application.Quit();
54. }
55.
56. //Inicia a aplicacao
57. public static void Main (string[] args)
58. {
59. new Aplicacao(args);
60. }
61. }
62.

Compilando & Executando

$ mcs -pkg:gtk-sharp-2.0 -pkg:glade-sharp-2.0 -resource:simple.glade simple.cs


$ ./simple.exe

Você também pode executar assim:

$ mono simple.exe

Ruby
Lauro contribuiu com esse código em Ruby para o artigo.

Veja mais em: Pacotes


Necessários
http://ruby-gnome2.sourceforge.jp
http://ruby-gnome2.sourceforge.jp/pt_BR/hiki.cgi?tutoriais
http://times.usefulinc.com/2006/01/30-ruby-gnome ruby-gnome2

Código

14 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

1. #!/usr/bin/ruby
2. # Arquivo: aplicacao.rb
3.
4. require 'libglade2'
5.
6. class Aplicacao
7. # "Construtor"
8. def initialize(path)
9. # Cria o objeto GladeXML e associa os sinais aos
10. # metodos com o mesmo nome atraves do bloco passado
11. @glade = GladeXML.new(path){ |handler| method(handler) }
12.
13. #define os "widgets" e valores padroes
14. @combo = @glade.get_widget("combo")
15. @etiqueta = @glade.get_widget("etiqueta")
16. @janela = @glade.get_widget("janelaPrincipal")
17. @combo.active = 1 # Valor padrao = Tamanho normal
18. @janela.show_all
19.
20. Gtk.main #Iniciando loop de espera por eventos
21. end
22.
23. # Signal handler: Responde a mudancas no combo box.
24. def mudaTamanho
25. case @combo.active
26. when 0
27. @etiqueta.set_markup("<small>Texto de Exemplo.</small>")
28. when 1
29. @etiqueta.set_markup("Texto de Exemplo.")
30. when 2
31. @etiqueta.set_markup("<big>Texto de Exemplo.</big>")
32. end
33. end
34.
35. # Signal handler: Sai do programa
36. def sair
37. Gtk.main_quit #Saindo do loop
38. end
39. end
40.
41. Aplicacao.new("./simple.glade")
42.

Executando

$ ruby ./aplicacao.rb

Lauro: terminar parte de haskell

Haskell
Bem, para quem disse que Haskell é uma linguagem apenas acadêmica, sem bibliotecas, existe o Gtk2Hs, que
contém bindings para a Gtk, libglade e Cairo.
Pacotes Necessários
De maneira parecida a C, as funções são chamadas com o formato "função widget argumentos". Por exemplo,
a função onDestroy recebe um widget (window, no caso) e uma função (mainQuit) que será chamada quando
o sinal Destroy for enviado para window. gtk2hs (versão usada: 0.9.10)

Muitas funções retornam o tipo Maybe, usado em casos que a funções pode retornar um valor ou não. Mais
informações podem ser vistas neste link [1] (http://www.haskell.org/onlinereport/maybe.html) .

Mais informações em:

http://haskell.org/gtk2hs/overview/

Código

15 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

1. -- Arquivo: aplicacao.hs
2. import Graphics.UI.Gtk
3. import Graphics.UI.Gtk.Glade
4.
5. main::IO()
6. main = do
7. initGUI
8. xmlMaybe <- xmlNew "example.glade"
9. let xml = case xmlMaybe of
10. (Just xml) -> xml
11. Nothing -> error "File not found"
12. window <- xmlGetWidget xml castToWindow "janelaPrincipal"
13. label <- xmlGetWidget xml castToLabel "etiqueta"
14. combo <- xmlGetWidget xml castToComboBox "combo"
15. comboBoxSetActive combo 0
16. onDestroy window mainQuit
17. onChanged combo $ do
18. indexM <- comboBoxGetActive combo
19. let index = case indexM of
20. (Just index) -> index
21. Nothing -> 0
22. let string = case index of
23. 0 -> "<small>Texto de exemplo</small>"
24. 1 -> "Texto de exemplo"
25. 2 -> "<big>Texto de exemplo</big>"
26. labelSetMarkup label string
27. widgetShowAll window
28. mainGUI

Compilando & Executando

$ ghc --make aplicacao.hs -o aplicacao


$ aplicacao

DevHelp
Poucas coisas são tão úteis para programar quanto documentação (com exceção talvez do café). O DevHelp é um navegador de ajuda,
documentação e APIs do GNOME. Seu pacote no Debian/Ubuntu chama-se devhelp, mas esse sozinho serve tanto quanto café sem cafeína. O
recheio do DevHelp está em pacotes com a terminação -doc (embora nem todo -doc vá parar no DevHelp), por exemplo: libgtk2.0-doc, glade-doc,
libgtkmm-2.4-doc, python-gtk2-doc.

Recomendo fortemente sua instalação. E é o fim por enquanto.

Autor: Marcelo Lira

:
Atribuição-Compatilhamento pela mesma licença 2.5 (http://creativecommons.org/licenses/by-sa/2.5/)

16 de 17 16/09/2009 16:35
Mantendo A Sanidade Com O Glade - CInLUG http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade

Retirado de "http://www.cin.ufpe.br/~cinlug/wiki/index.php/Mantendo_A_Sanidade_Com_O_Glade"

Page categories: !Esboços | Artigos

Vistas

Artigo
Discussão
Editar
História

Está página foi modificada pela última vez em 02:07, 7 Agosto 2009.
Esta página foi acessada 22 972 vezes.
Sobre a CInLUG
Disclaimers

17 de 17 16/09/2009 16:35

Você também pode gostar