Obra: GTK+/Começando
capítulo começando primeira coisa fazer claro descarregar código fonte do gtk instalá lo você sempre poderá obter última versão de ftp ftp gtk org você também pode ver outras fontes de informação sobre gtk em http www gtk org em inglês gtk usa gnu autoconf para configuração assim que desempacotar código fonte digite configure help para ver uma lista de opções distribuição do código fonte do gtk também contém código completo para todos os exemplos usados neste tutorial além de makefiles para ajudar na compilação também possível usar distribuições binárias disponíveis para várias distribuições de linux sistemas unix consulte sistema de pacotes da sua distribuição para ambiente windows para iniciar nossa introdução ao gtk começaremos com programa mais simples possível ele criará uma janela de pixels não terá nenhuma maneira de ser terminado não ser pelo shell ou por algum gerenciador de processos include int main int argc char argv gtkwidget window gtk_init argc argv window gtk_window_new gtk_widget_show window gtk_main return você pode compilar programa acima com gcc com comando gcc base base pkg config cflags libs gtk significado das opções não usuais de compilação está explicado abaixo em compilando hello world todos os programas irão claro incluir arquivo gtk gtk que declara as variáveis funções estruturas etc que serão usadas na sua aplicação gtk linha seguinte gtk_init argc argv chama função gtk_init gint argc gchar argv que será chamada em todas as aplicações gtk ela ajusta algumas coisas para nós como aparência padrão os mapas de cores depois segue para chamar gtk_init gint argc gchar argv esta função inicializa biblioteca para uso configura os tratadores padrão de sinal verifica os argumentos passados para sua aplicação na linha de comando procurando por um dos seguintes gtk module fatal warnings gtk debug gtk no debug gdk debug gdk no debug display sync name class função remove esses itens da lista de argumentos deixando tudo que não reconhecer para sua aplicação interpretar ou ignorar isso cria um conjunto de argumentos padrão aceitos por todas as aplicações gtk as próximas duas linhas de código criam exibem uma janela window gtk_window_new gtk_widget_show window argumento especifica que queremos que janela seja submetida decoração ao posicionamento do gerenciador de janelas em vez de criar uma janela de tamanho uma janela sem controles widgets ajustada para por padrão de modo que você ainda possa manipulá la função gtk_widget_show deixa gtk saber que terminamos de ajustar os atributos deste widget que ele pode agora ser exibido última linha responsável por entrar no loop de processamento principal do gtk gtk_main gtk_main outra chamada que você verá em toda aplicação gtk quando controle chega esse ponto gtk irá apenas ficar espera de eventos do como apertamento de botões ou teclas tempos limite ou notificações de em arquivos no nosso exemplo simples no entanto os eventos são ignorados hello world em gtk agora um programa com um widget um
lo simples no entanto os eventos são ignorados hello world em gtk agora um programa com um widget um botão clássico programa hello world la gtk include uma novidade que vem do os comentarios podem ser escritos com ou esta uma função callback os argumentos de dados são ignorados neste exemplo mais sobre callbacks abaixo static void hello gtkwidget widget gpointer data g_print hello world static gboolean delete_event gtkwidget widget gdkevent event gpointer data se você retornar false no tratador do sinal delete_event gtk emitirá sinal destroy retornar true significa que você não quer que janela seja destruída isso útil para exibir diálogos do tipo tem certeza de que deseja sair g_print evento delete ocorreu mude true para false janela principal será destruída com um delete_event return true outro callback static void destroy gtkwidget widget gpointer data gtk_main_quit int main int argc char argv gtkwidget tipo de dado para os widgets gtkwidget window gtkwidget button esta função chamada em todas as aplicações gtk argumentos da linha de comando são interpretados retornados aplicação gtk_init argc argv criar uma nova janela window gtk_window_new quando janela recebe sinal delete_event dado pelo gerenciador de janelas geralmente pela opção fechar ou na barra de título nós pedimos que ela chame função delete_event como definido acima os dado passado para função callback null ignorado g_object window delete_event g_callback delete_event null aqui conectamos evento destroy um tratador de sinal esse evento ocorre quando chamamos na janela ou se retornamos false no callback delete_event g_object window destroy g_callback destroy null ajusta largura da borda da janela gtk_container window coloca um nome na janela gtk_window window aqui nome da janela cria um novo botão com texto hello world button hello world quando botão recebe sinal clicked chamará função hello passando null como argumento hello definida acima g_object button clicked g_callback hello null isso fará com que janela será destruída pela chamada window quando botão for clicado clicked novamente sinal destroy poderia vir daqui ou do gerenciador de janelas g_object button clicked g_callback g_object window isto empacota botão na janela um recipiente gtk gtk_container window button passo final exibir widget recém criado gtk_widget_show button janela gtk_widget_show window toda aplicação gtk deve ter uma chamada gtk_main controle termina aqui espera por um evento como um apertamento de tecla ou evento do mouse gtk_main return compilando hello world para compilar use gcc wall helloworld helloworld pkg config cflags gtk pkg config libs gtk usamos programa pkg config que pode ser obtido de www freedesktop org esse programa lê arquivo pc que vem com gtk para determinar as opções do compilador necessárias para compilar programas que usam gtk pkg config cflags gtk mostrará uma lista de diretórios de inclusão nos quais compilador deve olhar pkg config libs gtk mostrará lista de bibliotecas às quais com
lusão nos quais compilador deve olhar pkg config libs gtk mostrará lista de bibliotecas às quais compilador deve ligar executável os diretórios nos quais encontrá las no exemplo acima os dois comandos poderiam ter sido combinados num só como pkg config cflags libs gtk note que você deve digitar um acento grave não uma aspa simples as bibliotecas que costumam ser usadas são biblioteca gtk lgtk biblioteca de widgets baseada no gdk biblioteca gdk lgdk intermediário da xlib biblioteca gdk pixbuf lgdk_pixbuf biblioteca de manipulação de imagens biblioteca pango lpango para texto biblioteca gobject lgobject que contém sistema de tipos no qual baseado gtk biblioteca gmodule lgmodule usada para carregar extensões em tempo de execução biblioteca glib lglib que contém funções miscelâneas apenas g_print usada neste exemplo particular gtk construído sobre glib portanto você sempre precisará desta biblioteca veja seção sobre glib para mais detalhes biblioteca xlib lx que usada pelo gdk biblioteca xext lxext ela contém código para pixmaps compartilhados na memória outras extensões biblioteca de matemática lm usada pelo gtk para vários propósitos teoria dos sinais callbacks nota na versão sistema de sinais foi movido do gtk para glib portanto as funções tipos explicadas nesta seção têm prefixo g_ não gtk_ não falaremos em detalhes sobre as extensões do sistema de sinais da glib em relação ao do gtk antes de olharmos detalhadamente para programa helloworld discutiremos sinais callbacks gtk uma biblioteca movida eventos que significa que ele dormirá na função gtk_main até que um evento ocorra controle seja passado para função apropriada essa passagem de controle feita usando idéia de sinais note que esses sinais não são os mesmos que os sinais de sistema unix não são através deles implementados apesar de terminologia ser quase idêntica quando um evento ocorre como pressionamento de um botão do mouse sinal apropriado será emitido pelo widget que foi pressionado assim que gtk faz maior parte de seu trabalho útil há sinais que todos os widgets herdam como destroy destruir há sinais específicos de um certo widget ou conjunto de widgets como toggled alternado num botão de alternar para fazer um botão realizar uma ação configuramos um tratador de sinal para capturar esses sinais chamar função apropriada isso feito com uma função como gulong gpointer object const gchar name gcallback func gpointer func_data onde primeiro argumento widget que emitirá sinal segundo nome do sinal que você deseja capturar terceiro argumento função que você deseja que seja chamada na captura do evento quarto um ponteiro para os dados que você deseja passar para essa função função especificada no terceiro argumento chamada de função de callback deve estar geralmente na forma void callback_func gtkwidget widget outros argumentos do sinal gpointer callback_data onde primeiro argumento será um ponteiro para widget que emitiu sinal último um ponteiro para os dados passados como último argumento p
teiro para widget que emitiu sinal último um ponteiro para os dados passados como último argumento para função como mostrado acima note que maneira acima para declaração de uma função callback apenas uma forma geral já que alguns sinais específicos de widgets requerem parâmetros diferentes de chamada outra chamada usada no exemplo helloworld gulong gpointer object const gchar name gcallback func gpointer callback_data mesmo que exceto por um aspecto instância na qual sinal emitido os dados definidos pela chamada serão invertidos quando tratador for chamado então quando essa função for usada para conectar sinais callback deve ser da forma void callback_func gpointer callback_data other signal arguments gtkwidget widget onde objeto normalmente um widget no entanto não costumamos definir callbacks para função eles são normalmente usados para chamar quando um sinal emitido em algum outro objeto uma função do gtk que aceita apenas um widget ou objeto como argumento no exemplo helloworld conectamos ao sinal clicked no botão mas chamamos na janela se seus callbacks precisam de dados adicionais use no lugar de eventos além do mecanismo de sinais acima descrito há um conjunto de eventos que refletem mecanismo de eventos do podem se também associar callbacks esses eventos que são event evento apertamento de botão soltamento de botão scroll_event rolagem notificação de movimento delete_event deleção destroy_event destruição expose_event key_press_event apertamento de tecla soltamento de tecla notificação de entrada notificação de saída configure_event configuração focus_in_event entrada de foco focus_out_event saída de foco map_event mapeamento unmap_event desmapeamento notificação de propriedade limpeza da seleção requisição de seleção notificação de seleção proximidade notificação de visibilidade client_event cliente no_expose_event estado da janela para conectar uma função callback um desses eventos use função como descrito acima usando um dos nomes de eventos acima como parâmetro name função callback para eventos tem uma forma ligeiramente diferente da usada para os sinais gint callback_func gtkwidget widget gdkevent event gpointer callback_data gdkevent um union em cujo tipo dependerá de qual dos eventos acima ocorreu para podermos distinguir que evento foi lançado cada alternativa possível tem um membro chamado type tipo que reflete evento sendo lançado os outros componentes da estrutura dependerão do tipo do evento são valores possíveis para tipo gdk_nothing gdk_delete gdk_destroy gdk_expose gdk_ button_press gdk_ button_press gdk_key_press gdk_key_release gdk_configure gdk_map gdk_unmap gdk_drag_enter gdk_drag_leave gdk_drag_motion gdk_drag_status gdk_drop_start gdk_no_expose gdk_scroll gdk_setting assim para conectar uma função callback um desses eventos escreveríamos algo como g_object button g_callback null esse código assume que button um widget button botão agora quando mouse rato está sobre esse botão um botão do mouse for pressionado função s
utton botão agora quando mouse rato está sobre esse botão um botão do mouse for pressionado função será chamada essa função pode ser declarada como static gboolean gtkwidget widget gdkeventbutton event gpointer data note que podemos declarar segundo argumento como do tipo gdkeventbutton porque sabemos que tipo de evento ocorrerá para que essa função seja chamada valor retornado nessa função indica se evento deve ser propagado pelo mecanismo de tratamento de eventos do gtk retornar true indica que evento foi tratado que não deve ser mais propagado retornar false continua tratamento normal de eventos veja seção sobre manipulação avançada de eventos sinais para obter mais detalhes deste processo de propagação para detalhes nos tipos de dados gdkevent veja apêndice tipos de evento do gdk as apis de seleção arrastar soltar do gdk também lançam certos eventos refletidos no gtk pelos sinais veja sinais no widget de origem sinais no widget de destino para detalhes da assinatura das funções callback para esses sinais selection_get drag_end_event drag_motion drag_drop drag_data_get analisando hello world agora que já conhecemos teoria por trás disso vamos tornar as coisas mais claras percorrendo todo código do exemplo helloworld esta função callback que será chamada quando botão pressionado clicado aqui ignoramos tanto widget quanto os dados mas não difícil fazer coisas com eles próximo exemplo usará argumento data para nos dizer qual dos botões foi pressionado static void hello gtkwidget widget gpointer data g_print hello world próximo callback um pouco especial evento delete ocorre quando gerenciador de janelas envia esse evento para aplicação podemos escolher que fazer respeito desse evento ignorá lo dar algum tipo de resposta como uma mensagem do tipo tem certeza de que deseja sair ou simplesmente terminar aplicação valor que você retornar nesse callback informa ao gtk que ação tomar retornando true informamos que não queremos que sinal destroy seja emitido para que nossa aplicação continue executar retornando false pedimos emissão do sinal destroy que por sua vez chamará nosso tratador de sinal destroy static gboolean delete_event gtkwidget widget gdkevent event gpointer data g_print delete event occurred return true aqui está outra função callback que causa término do programa chamando gtk_main_quit essa função diz ao gtk que ele deve sair da função gtk_main assim que ele receber controle de volta static void destroy gtkwidget widget gpointer data gtk_main_quit assumimos que você conhece função main sim assim como em outras aplicações toda aplicação gtk terá também uma função dessa int main int argc char argv esta próxima parte declara ponteiros para uma estrutura do tipo gtkwidget esses são usados abaixo para criar uma janela um botão gtkwidget window gtkwidget button aqui está nosso gtk_init novamente como antes essa função inicializa biblioteca interpreta os argumentos de linha de comando encontrados os argumentos reconhecidos pelo gtk gdk são rem
rpreta os argumentos de linha de comando encontrados os argumentos reconhecidos pelo gtk gdk são removidos da lista argc argv são modificados retirando se quaisquer rastro da existência desses argumentos que permitirá que sua aplicação interprete os argumentos restantes corretamente gtk_init argc argv método para criar uma nova janela bastante direto aloca se memória para estrutura gtkwidget window de modo que ponteiro agora aponte para uma estrutura válida função prepara uma nova janela que no entanto não será mostrada até que chamemos gtk_widget_show window pelo final do nosso programa window gtk_window_new aqui estão dois exemplos de como conectar um tratador de sinal um objeto neste caso janela aqui os sinais delete_event destroy são interceptados primeiro emitido quando usamos gerenciador de janelas para terminar janela ou quando usamos chamada passando widget da janela como objeto ser destruído segundo emitido quando no tratador de delete_event retornamos false g_object g_callback são macros que realizam conversão casting verificação de tipos além de ajudar na legibilidade do código g_object window delete_event g_callback delete_event null g_object window destroy g_callback destroy null esta próxima função usada para ajustar um atributo de um objeto do tipo container ela apenas faz com que janela tenha ao seu redor uma área em branco de pixels de largura onde nenhum widget irá ficar há outras funções similares para as quais olharemos na seção ajustando atributos de controles novamente gtk_container uma macro para realizar conversão de tipos gtk_container window esta chamada cria um novo botão ela aloca espaço na memória para uma nova estrutura gtkwidget inicializa faz ponteiro button apontar para ela botão terá nele etiqueta hello world quando exibido button hello world aqui mandamos botão fazer algo de útil anexamos ele um tratador de sinal para que nossa função hello seja chamada quando ele emitir sinal clicked os dados são ignorados então simplesmente passamos null para callback hello obviamente sinal clicked emitigo quando botão clicado premido com mouse rato g_object button clicked g_callback hello null também vamos usar esse botão para sair do nosso programa isso ilustra como sinal destroy pode vir tanto do gerenciador de janelas quanto do nosso programa quando botão apertado clicked como no caso de cima chama se callback hello depois este na ordem em que eles foram configurados você pode ter tantos callbacks quanto precisar todos serão executados na ordem em que você os conectou já que função aceita apenas um gtkwidget como argumento usamos aqui função em vez de simplesmente g_object button clicked g_callback g_object window esta uma chamada de empacotamento que será explicada fundo mais adiante em empacotando widgets mas razoavelmente fácil de ser entendida ela simplesmente diz ao gtk que botão deve ser colocado na janela onde ele será exibido note que um container gtk só pode conter um widget mas há outros widgets que serão descrit
á exibido note que um container gtk só pode conter um widget mas há outros widgets que serão descritos mais tarde que são desenhados para dispor vários widgets de várias maneiras gtk_container window button agora já temos tudo configurado da maneira que queremos que seja com todos os tratadores de sinal no lugar botão colocado na janela no lugar que deverá estar mandamos gtk mostrar show os widgets na tela widget da janela mostrado por último para que janela apareça inteira de uma vez em vez de vermos primeiro janela aparecer depois botão se formar dentro da janela claro que com um exemplo tão simples você dificilmente ou nunca notaria essa diferença gtk_widget_show button gtk_widget_show window claro chamamos função gtk_main que aguarda eventos do servidor irá coordenar as emissões de sinais quando esses eventos forem detectados gtk_main retorno final controle do programa volta para cá quando gtk_quit for chamada return agora quando clicarmos botão do mouse num botão do gtk esse widget emitirá sinal clicked para podermos usar essa informação nosso programa cria um tratador de sinal para interceptar esse sinal despachando função de nossa escolha no nosso exemplo quando botão que criamos apertado função hello chamada com um argumento null depois próximo tratador para esse sinal chamado função passando ela widget da janela como argumento destruindo esse widget com isso janela emite sinal destroy que interceptado faz chamar nossa função callback destroy que simplesmente sai do gtk outro caminho usar gerenciador de janelas para fechar janela que causará emissão do sinal delete_event isso chamará nosso tratador de sinal delete_event nele se retornarmos true janela será deixada como está nada irá acontecer retornando false fazemos gtk emitir sinal destroy que claro chama callback destroy deixando gtk