Você está na página 1de 6

http://www.vivaolinux.com.br/artigo/Introducao-a-GTK+-em-C/?

pagina=1

Introduo
Desenvolver interfaces grficas , para a maioria dos programadores (como eu, por exemplo), um martrio. Para mim, comea do fato que debugar uma interface grfica infinitamente mais trabalhoso que debugar um aplicativo em console, mas o principal problema a meu ver que eu no tenho a menor noo de esttica (ou pelo menos a minha noo costuma ser bem diferente da noo dos usurios finais). De qualquer forma, quando o pblico alvo de um aplicativo no tem a menor ideia do que uma console, fundamental termos uma interface grfica que torne simples para qualquer pessoa o uso das funes desse aplicativo. Como no h muito como fugir das interfaces grficas, preciso escolher uma forma de desenvolver essas interfaces. Temos diversas bibliotecas grficas, mas vamos tratar especificamente da biblioteca GTK+ por algumas caractersticas: Licena LGPL, o que d uma grande flexibilidade na licena do aplicativo a ser desenvolvido; Bem documentada, o que fundamental para o desenvolvedor, afinal ningum quer perder tempo tentando adivinhar pra que serve cada funo da biblioteca; Com a GTK+ voc consegue migrar (pelo menos a interface grfica) para muitos sistemas, at para o Windows e dispositivos com framebuffer. Neste artigo farei uma breve introduo de como comear a desenvolver interfaces grficas utilizando a biblioteca GTK+ e a linguagem C.

Requisitos
Primeiro de tudo, precisamos da biblioteca e de um ambiente de desenvolvimento. Nesse ponto voc pode escolher baixar o cdigo fonte, compilar e instalar a biblioteca... alguns anos atrs (quando eu ainda era fantico pelo Slackware) o que eu faria, mas hoje o que eu fao um apt-get (ser que estou ficando preguioso?). No Debian o seguinte: # apt-get install build-essential para instalar gcc, bibliotecas padres e essas coisas. # apt-get install libgtk2.0-dev para instalar a biblioteca gtk+, aceite todas as dependncias. Para quem quiser fazer a partir do cdigo fonte, fazer o famoso: # ./configure # make # make install

Pra ver se est tudo certo (ou quase certo): # pkg-config --cflags --libs gtk+-2.0 Deve retornar algo parecido com: -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/directfb -I/usr/include/libpng12 -I/usr/include/pixman-1 -lgtkx11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgobject2.0 -lgmodule-2.0 -ldl -lglib-2.0 Esse artigo no uma introduo a C, vou partir do princpio que pelo menos o bsico da linguagem de programao conhecido pelo leitor.

Primeiro programa... que no faz nada


<!-Com nosso ambiente pronto, vamos comear a codificar. Crie o arquivo teste.c e digite o seguinte contedo (pode digitar em qualquer editor de texto que salve como texto puro): #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { GtkWidget *janela; gtk_init(&argc, &argv); janela=gtk_window_new(GTK_WINDOW_TOPLEVEL); return 0; } Uma explicao das linhas: GtkWidget *janela; Em gtk todos os componentes (janelas, botes, labels) so filhos de uma classe GtkWidget, por isso declaramos ponteiros do tipo GtkWidget. gtk_init(&argc, &argv); Antes de qualquer chamada para funes gtk precisamos inicializar a biblioteca, se voc esquecer essa linha, vai receber um monte de erros e seu aplicativo no ir funcionar, apesar de compilar normalmente. janela=gtk_window_new(GTK_WINDOW_TOPLEVEL); Quase todo aplicativo tem uma janela, e aqui declaramos que o ponteiro *janela declarado com o tipo GtkWidget do tipo window. isso que faremos com todos os widgets que formos utilizar.

Vamos compilar: $ gcc -o teste teste.c `pkg-config --cflags --libs gtk+-2.0` E vamos rodar: $ ./teste E no acontece nada... na prxima pgina vamos acrescentar mais algumas linhas que resolvero esse problema.

Agora sim
Vamos editar de novo o arquivo teste.c e acrescentar mais algumas linhas: #include <stdio.h> #include <gtk/gtk.h> int main(int argc, char **argv) { GtkWidget *janela; gtk_init(&argc, &argv); janela=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_show_all(janela); gtk_main(); return 0; } Ah.... faltava exibir a janela, bem intuitivo, no? gtk_widget_show_all(janela); Mas pra que serve o gtk_main(); ? Essa linha que inicia o main loop, que um loop de eventos. ele que fica esperando alguma interao com a interface grfica e vai executando o que solicitado. Recompile o programa e execute-o novamente. Legal, agora abre uma janela, mas tambm no acontece muita coisa. Vamos fechar o programa.... ops a janela fecha, mas meu console continua preso em algo....nada que um Ctrl+C no resolva...

Sinais
normal minha console ficar travada quando eu fecho um programa? Claro que no. Se voc abrir outro terminal e usar um ps, vai ver que o aplicativo continua em execuo. Quando fechamos a janela, no quer dizer que encerramos o aplicativo, pelo menos no se no definirmos que dessa forma que o programa deve se comportar. Lembra do main loop? Ele continua esperando eventos, apesar de fecharmos a janela. Se queremos que o programa seja encerrado quando fechamos a janela, precisamos encerrar o main loop, da ento ele vai executar tudo que est depois do gtk_main(); o que no nosso caso o return 0;. Edite o arquivo teste.c e acrescente mais uma linha: #include <stdio.h> #include <gtk/gtk.h> int main(int argc, char **argv) { GtkWidget *janela; gtk_init(&argc, &argv); janela=gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(G_OBJECT(janela), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(janela); gtk_main(); return 0; } A linha que acrescentamos conecta um sinal ao objeto janela. Esse sinal espera que o objeto janela emita um evento do tipo "destroy" e quando isso acontece chama a funo gtk_main_quit, e no passa nenhum argumento para essa funo(NULL). Recompile o programa e tente execut-lo novamente. Agora o programa deve se encerrar quando a janela fechada. Isso ocorre porque quando a janela fechada ela emite um sinal "destroy", que faz com que a funo gtk_main_quit() seja executada, e essa funo encerra o main loop. Conectar eventos a maneira que usamos para fazer qualquer coisa em GTK+ (e na maioria das bibliotecas grficas). Quando um evento ocorre, ele entra na fila do loop de eventos (main loop), que vai executando as funes conectadas a cada evento (se houver alguma funo 'conectada' ao evento).

Mais um exemplo
Vamos fazer mais um exemplo, com um pouco mais de funcionalidade. Vamos fazer um conversor de temperatura (quem j no fez um.... talvez em VB? :-)). #include <stdio.h> #include <gtk/gtk.h> GtkWidget *entrada; GtkWidget *label_saida; gboolean converter(GtkButton *button, gpointer data) { double celsius; double fahrenheit; char texto[128]; celsius=atol(gtk_entry_get_text(GTK_ENTRY(entrada))); fahrenheit=celsius*1.8+32; sprintf(texto, "%.1f C = %.1f F", celsius, fahrenheit); gtk_label_set_text(GTK_LABEL(label_saida), texto); return FALSE; } int main(int argc, char **argv) { GtkWidget *janela; GtkWidget *conteudo; GtkWidget *label_entrada; GtkWidget *botao; gtk_init(&argc, &argv); janela=gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(janela), GTK_WIN_POS_CENTER); conteudo=gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(janela), conteudo); label_entrada=gtk_label_new("Digite a temperatura em C"); gtk_box_pack_start(GTK_BOX(conteudo), label_entrada, FALSE, FALSE, 0); entrada=gtk_entry_new(); gtk_box_pack_start(GTK_BOX(conteudo), entrada, FALSE, FALSE, 0); botao=gtk_button_new_with_label("Converter para F"); gtk_box_pack_start(GTK_BOX(conteudo), botao, FALSE, FALSE, 0); label_saida=gtk_label_new("C = F"); gtk_box_pack_start(GTK_BOX(conteudo), label_saida, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(janela), "destroy", G_CALLBACK(gtk_main_quit), NULL);

g_signal_connect(G_OBJECT(botao), "clicked", G_CALLBACK(converter), NULL); gtk_widget_show_all(janela); gtk_main(); return 0; } Agora uma explicao mais detalhada: Primeiro declaramos a janela e definimos a posio dela; Criamos um box de contedo do tipo vbox que organiza os componentes verticalmente, adicionamos o box janela; Criamos um label de entrada e acrescentamos ele ao box de contedo; Criamos um componente de entrada de dados e adicionamos ao box de contedo; Criamos um boto com texto e o adicionamos ao box de contedo; Criamos um label com o resultado da converso e o adicionamos ao box de contedo; Conectamos o sinal de "destroy" janela fazendo com que chame a funo gtk_main_quit(), que encerra o main loop; Conectamos o sinal "clicked" ao boto fazendo com que execute a funo converter(); Exibimos tudo que est dentro da janela; Compilando e rodando, nosso conversor deve funcionar.

Concluso
Utilizar a GTK+ para desenvolver interfaces grficas torna-se bem intuitivo depois de um tempo, principalmente pelo fato de que o nome das funes so bem intuitivos. bvio que nosso conversor de unidades tem vrios problemas (ele aceita texto no campo de entrada por exemplo...), mas ele demonstra bem a funcionalidade da GTK+. fundamental dar uma boa olhada na documentao disponvel em library.gnome.org/devel/gtk/, s assim comeamos a nos familiarizar com todos os componentes disponveis e todas as opes disponveis. Em casos de dvidas, um bom frum de discusso tambm pode ajudar: http://www.gtkforums.com Uma coisa legal sobre a GTK+ que existem bindings para vrias linguagens, como PHP, python, C++ e outras. Espero que o artigo o ajude a pelo menos iniciar o uso da GTK+ para o desenvolvimento de interfaces grficas.

Você também pode gostar