Você está na página 1de 72

Python-GTK

23 de maio de 2007

Sumrio
I

Sobre essa Apostila

II Informaes Bsicas

III Python-GTK

10

1 O que o Curso

11

2 Plano de ensino
2.1 Objetivo . . .
2.2 Pblico Alvo .
2.3 Pr-requisitos
2.4 Descrio . .
2.5 Metodologia .
2.6 Cronograma
2.7 Programa . .
2.8 Avaliao . .
2.9 Bibliografia .

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

12
12
12
12
12
12
13
13
13
14

3 Lio 1 - Apresentando PyGTK


15
3.1 Um breve histrico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Primeiros passos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3 Conferindo a instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4 Lio 2 - Apresentando Widgets, Signals e Callbacks
19
4.1 Conceitos bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2 Um exemplo prtico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5 Lio 3 - Widgets elementares
24
5.1 Empacotando widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5.2 O widget do boto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6 Lio 4 - Widgets miscelneas 1
6.1 Adjustments . . . . . . . . . .
6.2 Widgets de faixa de valores .
6.3 Labels . . . . . . . . . . . . .
6.4 reas com barras de rolagem
6.5 Exemplo . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
1

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

34
34
35
37
38
38

CDTC

Centro de Difuso de Tecnologia e Conhecimento

7 Lio 5 - Widgets miscelneas 2


7.1 Barras de progresso . . . . .
7.2 Dialogs . . . . . . . . . . . .
7.3 Barras de status . . . . . . .
7.4 Exemplo . . . . . . . . . . . .

.
.
.
.

8 Lio 6 - Widgets miscelneas 3


8.1 Menus . . . . . . . . . . . . . .
8.2 Entrada de texto . . . . . . . .
8.3 Spin buttons . . . . . . . . . .
8.4 Dilogo de seleo de arquivo

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

Brasil/DF

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

43
43
44
45
45

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

51
51
53
54
55

9 Lio 7 - Controle avanado de layout


9.1 Alignment . . . . . . . . . . . . . . .
9.2 Continer Fixed . . . . . . . . . . . .
9.3 Continer layout . . . . . . . . . . .
9.4 Frames . . . . . . . . . . . . . . . .
9.5 Paned Window . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

58
58
59
60
61
62

.
.
.
.

.
.
.
.

10 Lio 8 - Progredindo com PyGTK


64
10.1 Progredindo com PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
10.2 Matria extra: Criando interfaces grficas usando PyGTK e Glade . . . . . . . . . . 64
10.3 Despedidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Parte I

Sobre essa Apostila

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Contedo
O contedo dessa apostila fruto da compilao de diversos materiais livres publicados na internet, disponveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br.
O formato original deste material bem como sua atualizao est disponvel dentro da licena
GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seo de
mesmo nome, tendo inclusive uma verso traduzida (no oficial).
A reviso e alterao vem sendo realizada pelo CDTC (suporte@cdtc.org.br) desde outubro
de 2006. Crticas e sugestes construtivas so bem-vindas a qualquer tempo.

Autores
A autoria deste de responsabilidade de Pedro Guerra Brando.
O texto original faz parte do projeto Centro de Difuso de Tecnologia e Conhecimento, que
vem sendo realizado pelo ITI (Instituto Nacional de Tecnologia da Informao) em conjunto com
outros parceiros institucionais, atuando em conjunto com as universidades federais brasileiras
que tem produzido e utilizado Software Livre, apoiando inclusive a comunidade Free Software
junto a outras entidades no pas.
Informaes adicionais podem ser obtidas atravs do email ouvidoria@cdtc.org.br, ou da
home page da entidade, atravs da URL http://www.cdtc.org.br.

Garantias
O material contido nesta apostila isento de garantias e o seu uso de inteira responsabilidade do usurio/leitor. Os autores, bem como o ITI e seus parceiros, no se responsabilizam
direta ou indiretamente por qualquer prejuzo oriundo da utilizao do material aqui contido.

Licena
Copyright 2006, Instituto Nacional de Tecnologia da Informao (cdtc@iti.gov.br) .
Permission is granted to copy, distribute and/or modify this document under the terms
of the GNU Free Documentation License, Version 1.1 or any later version published by
the Free Software Foundation; with the Invariant Chapter being SOBRE ESSA APOSTILA. A copy of the license is included in the section entitled GNU Free Documentation
License.

Parte II

Informaes Bsicas

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Sobre o CDTC
Objetivo Geral
O Projeto CDTC visa a promoo e o desenvolvimento de aes que incentivem a disseminao de solues que utilizem padres abertos e no proprietrios de tecnologia, em proveito do
desenvolvimento social, cultural, poltico, tecnolgico e econmico da sociedade brasileira.
Objetivo Especfico
Auxiliar o Governo Federal na implantao do plano nacional de software no-proprietrio e
de cdigo fonte aberto, identificando e mobilizando grupos de formadores de opinio dentre os
servidores pblicos e agentes polticos da Unio Federal, estimulando e incentivando o mercado
nacional a adotar novos modelos de negcio da tecnologia da informao e de novos negcios
de comunicao com base em software no-proprietrio e de cdigo fonte aberto, oferecendo
treinamento especfico para tcnicos, profissionais de suporte e funcionrios pblicos usurios,
criando grupos de funcionrios pblicos que iro treinar outros funcionrios pblicos e atuar como
incentivadores e defensores de produtos de software no proprietrios e cdigo fonte aberto, oferecendo contedo tcnico on-line para servios de suporte, ferramentas para desenvolvimento de
produtos de software no proprietrios e de seu cdigo fonte livre, articulando redes de terceiros
(dentro e fora do governo) fornecedoras de educao, pesquisa, desenvolvimento e teste de produtos de software livre.

Guia do aluno
Neste guia, voc ter reunidas uma srie de informaes importantes para que voc comece
seu curso. So elas:
Licenas para cpia de material disponvel
Os 10 mandamentos do aluno de Educao a Distncia
Como participar dos foruns e da wikipdia
Primeiros passos
muito importante que voc entre em contato com TODAS estas informaes, seguindo o
roteiro acima.

Licena
Copyright 2006, Instituto Nacional de Tecnologia da Informao (cdtc@iti.gov.br).
6

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

dada permisso para copiar, distribuir e/ou modificar este documento sob os termos
da Licena de Documentao Livre GNU, Verso 1.1 ou qualquer verso posterior
pblicada pela Free Software Foundation; com o Capitulo Invariante SOBRE ESSA
APOSTILA. Uma cpia da licena est inclusa na seo entitulada "Licena de Documentao Livre GNU".

Os 10 mandamentos do aluno de educao online

1. Acesso Internet: ter endereo eletrnico, um provedor e um equipamento adequado


pr-requisito para a participao nos cursos a distncia.
2. Habilidade e disposio para operar programas: ter conhecimentos bsicos de Informtica necessrio para poder executar as tarefas.
3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distncia conta muitos pontos, pois ir colaborar para o processo ensino-aprendizagem pessoal,
dos colegas e dos professores.
4. Comportamentos compatveis com a etiqueta: mostrar-se interessado em conhecer seus
colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo.
5. Organizao pessoal: planejar e organizar tudo fundamental para facilitar a sua reviso
e a sua recuperao de materiais.
6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigaes e
realiz-las em tempo real.
7. Curiosidade e abertura para inovaes: aceitar novas idias e inovar sempre.
8. Flexibilidade e adaptao: requisitos necessrio mudana tecnolgica, aprendizagens
e descobertas.
9. Objetividade em sua comunicao: comunicar-se de forma clara, breve e transparente
ponto - chave na comunicao pela Internet.
10. Responsabilidade: ser responsvel por seu prprio aprendizado. O ambiente virtual no
controla a sua dedicao, mas reflete os resultados do seu esforo e da sua colaborao.

Como participar dos fruns e Wikipdia


Voc tem um problema e precisa de ajuda?
Podemos te ajudar de 2 formas:
A primeira o uso dos fruns de notcias e de dvidas gerais que se distinguem pelo uso:
. O frum de notcias tem por objetivo disponibilizar um meio de acesso rpido a informaes
que sejam pertinentes ao curso (avisos, notcias). As mensagens postadas nele so enviadas a
7

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

todos participantes. Assim, se o monitor ou algum outro participante tiver uma informao que
interesse ao grupo, favor post-la aqui.
Porm, se o que voc deseja resolver alguma dvida ou discutir algum tpico especfico do
curso. recomendado que voc faa uso do Forum de dvidas gerais que lhe d recursos mais
efetivos para esta prtica.
. O frum de dvidas gerais tem por objetivo disponibilizar um meio fcil, rpido e interativo
para solucionar suas dvidas e trocar experincias. As mensagens postadas nele so enviadas
a todos participantes do curso. Assim, fica muito mais fcil obter respostas, j que todos podem
ajudar.
Se voc receber uma mensagem com algum tpico que saiba responder, no se preocupe com a
formalizao ou a gramtica. Responda! E no se esquea de que antes de abrir um novo tpico
recomendvel ver se a sua pergunta j foi feita por outro participante.
A segunda forma se d pelas Wikis:
. Uma wiki uma pgina web que pode ser editada colaborativamente, ou seja, qualquer participante pode inserir, editar, apagar textos. As verses antigas vo sendo arquivadas e podem
ser recuperadas a qualquer momento que um dos participantes o desejar. Assim, ela oferece um
timo suporte a processos de aprendizagem colaborativa. A maior wiki na web o site "Wikipdia", uma experincia grandiosa de construo de uma enciclopdia de forma colaborativa, por
pessoas de todas as partes do mundo. Acesse-a em portugus pelos links:
Pgina principal da Wiki - http://pt.wikipedia.org/wiki/
Agradecemos antecipadamente a sua colaborao com a aprendizagem do grupo!

Primeiros Passos
Para uma melhor aprendizagem recomendvel que voc siga os seguintes passos:
Ler o Plano de Ensino e entender a que seu curso se dispe a ensinar;
Ler a Ambientao do Moodle para aprender a navegar neste ambiente e se utilizar das
ferramentas bsicas do mesmo;
Entrar nas lies seguindo a seqncia descrita no Plano de Ensino;
Qualquer dvida, reporte ao Frum de Dvidas Gerais.

Perfil do Tutor
Segue-se uma descrio do tutor ideal, baseada no feedback de alunos e de tutores.
O tutor ideal um modelo de excelncia: consistente, justo e profissional nos respectivos
valores e atitudes, incentiva mas honesto, imparcial, amvel, positivo, respeitador, aceita as
idias dos estudantes, paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar.
8

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

A classificao por um tutor desta natureza proporciona o melhor feedback possvel, crucial, e,
para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem. Este tutor
ou instrutor:
fornece explicaes claras acerca do que ele espera, e do estilo de classificao que ir
utilizar;
gosta que lhe faam perguntas adicionais;
identifica as nossas falhas, mas corrige-as amavelmente, diz um estudante, e explica porque motivo a classificao foi ou no foi atribuda;
tece comentrios completos e construtivos, mas de forma agradvel (em contraste com um
reparo de um estudante: os comentrios deixam-nos com uma sensao de crtica, de
ameaa e de nervossismo)
d uma ajuda complementar para encorajar um estudante em dificuldade;
esclarece pontos que no foram entendidos, ou corretamente aprendidos anteriormente;
ajuda o estudante a alcanar os seus objetivos;
flexvel quando necessrio;
mostra um interesse genuno em motivar os alunos (mesmo os principiantes e, por isso,
talvez numa fase menos interessante para o tutor);
escreve todas as correes de forma legvel e com um nvel de pormenorizao adequado;
acima de tudo, devolve os trabalhos rapidamente;

Parte III

Python-GTK

10

Captulo 1

O que o Curso

Python uma linguagem interpretada, orientada a objetos, extensvel e de fcil utilizao.


GTK+ (Gimp Tool Kit) uma biblioteca para criar interfaces grficas.
Para utiliz-las em conjunto, foi criado o PyGTK, que consiste em uma srie de mdulos para
prover uma interface ao Python para acesso ao GTK, possibilitando ao desenvolvedor a criao
de sistemas com interfaces grficas riqussimas.

11

Captulo 2

Plano de ensino
2.1 Objetivo
Habilitar tcnicos e programadores a usarem a biblioteca PyGTK, para Python.

2.2 Pblico Alvo


Tcnicos e Programadores que desejem trabalhar com PyGTK.

2.3 Pr-requisitos
Os usurios devero ser, necessariamente, indicados por empresas pblicas e ter certo conhecimento da linguagem Python. recomendvel um conhecimento mnimo nos recursos especficos da linguagem (por exemplo dicionrios e tuplas). Noes de orientao a objetos em
Python tambm so recomendveis.
No necessrio conhecimento prvio de GTK+.

2.4 Descrio
O curso de Introduo ao Python ser realizado na modalidade EAD e utilizar a plataforma
Moodle como ferramenta de aprendizagem. Ele composto de um mdulo de aprendizado que
ser dado na primeira semana e um mdulo de avaliao que ser dado na segunda semana. O
material didtico estar disponvel on-line de acordo com as datas pr-estabelecidas no calendrio. A verso utilizada para o PyGTK ser a 2.10.

2.5 Metodologia
O curso est dividido da seguinte maneira:

12

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

2.6 Cronograma
1 Semana - Introduo + Conceitos bsicos;
2 Semana - Conceitos avanados.
Todo o material est no formato de livro, e estar disponvel ao longo do curso. O livro poder
ser acessado quantas vezes forem necessrias. Aconselhamos a leitura de "Ambientao do
Moodle", para que voc conhea o produto de Ensino a Distncia, evitando dificuldades advindas
do "desconhecimento"sobre o mesmo.
Ao final de cada semana do curso ser disponibilizada a prova referente ao mdulo estudado
anteriormente que tambm conter perguntas sobre os textos indicados. Utilize o material de
cada semana e os exemplos disponibilizados para se preparar para prova.
Os instrutores estaro sua disposio ao longo de todo curso. Qualquer dvida deve ser
disponibilizada no frum ou enviada por e-mail. Diariamente os monitores daro respostas e esclarecimentos.

2.7 Programa
O curso oferecer o seguinte contedo:
Semana 1:
Viso Geral e Histrico;
Introduo;
Um breve exemplo;
Modificando parmetros;
Callbacks;
Widgets bsicos.
Semana 2:
1. Outras widgets;
2. Aperfeioando o controle de layout;
3. Automatizando o processo de criao de interfaces.

2.8 Avaliao
Toda a avaliao ser feita on-line.
Aspectos a serem considerados na avaliao:
Iniciativa e autonomia no processo de aprendizagem e de produo de conhecimento;
Capacidade de pesquisa e abordagem criativa na soluo dos problemas apresentados.
13

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Instrumentos de avaliao:
Participao ativa nas atividades programadas;
Avaliao ao final do curso;
O participante far vrias avaliaes referente ao contedo do curso. Para a aprovao e
obteno do certificado o participante dever obter nota final maior ou igual a 6.0 de acordo
com a frmula abaixo:
Nota Final = ((ML x 7) + (AF x 3)) / 10 = Mdia aritmtica das lies;
AF = Avaliaes.

2.9 Bibliografia
Site official: http://www.python.org
Guia: http://www.pygtk.org/pygtk2tutorial/index.html

14

Captulo 3

Lio 1 - Apresentando PyGTK


3.1 Um breve histrico
Embora o curso assuma um certo conhecimento de Python, no necessrio que o aluno
tenha experincia com GTK+. Entretanto, isto no nos impede de oferecer uma viso geral de
todos os componentes envolvidos.
GTK+
O GIMP Toolkit, popularmente conhecido por GTK+, um dos mais famosos toolkits voltados
para a criao de interfaces grficas (referidas GUIs daqui em diante). O que, ento, justifica a
parte GIMP do nome? Originalmente, foi idealizado para servir de base para o editor de imagens
GIMP (GNU Image Manipulation Program), mas acabou expandindo muito alm.
O GTK+ um dos pilares do famoso ambiente de janelas GNOME, portanto aplicaes baseadas nesta biblioteca podem ser facilmente identificadas pelo visual em comum.
Seus autores incluem Spencer Kimball, Peter Mattis e Josh MacDonald, todos os quais trabalhavam na Universidade de Berkeley poca de criao do GTK+/GIMP.

15

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Os menus, botes, formulrios, dropdowns e outros elementos da janela (widgets) possuem


um visual bastante padronizado, mesmo entre os vrios temas disponveis no GTK+ (acima representado est o tema padro da distribuio Ubuntu).
Python
Python uma linguagem de programao de alto nvel orientada a objetos. Seu criador, Guido
van Rossum, a criou em 1991 com o objetivo de enfatizar o esforo do programador sobre o esforo computacional, tornando-se uma linguagem de fcil aprendizagem.
Alm do mais, Python se difere de outras linguagens no quesito simplicidade e legibilidade.
Por exemplo, a indentao do cdigo de prima importncia para que o cdigo execute corretamente, o que conseqentemente facilita bastante a sua compreenso e padroniza os programas
com um look similar. O caractere ; no necessrio para indicar o trmino de um comando,
servindo a quebra de linha (\n) para tal.
Quanto ao aspecto de simplicidade, isto apenas se aplica ao ncleo da linguagem. H uma
vasta quantidade de bibliotecas disponveis, inclusive distribudas com o Python. Uma destas,
alis, o...

16

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

PyGTK
Como o leitor mais atento deve ter percebido, o objetivo deste curso aliar o Python e o GTK+
atravs da biblioteca PyGTK. Dispensando explicaes sobre a origem de seu nome, partiremos
para um overview geral.
O PyGTK um conjunto de wrappers (vulgarmente "envoltrios") para a biblioteca GTK+. Assim como o Python, o PyGTK software livre, no entanto distribudo sob a licena LGPL. de
autoria de um dos desenvolvedores do GNOME, James Henstridge, e hoje possui uma equipe
maior, inclusive com grande participao da comunidade atravs de patches e bug reports.
Um dos mritos do PyGTK ter sido escolhido como o ambiente de escolha para aplicaes
rodando nos sistemas do projeto One Laptop Per Child. Alm disso, algums outros projetos usam
o PyGTK, tais como:

Instalador Anaconda (usado no Fedora);


Bittorrent (cliente);
GNOME Sudoku (timo passatempo).

3.2 Primeiros passos


Talvez a melhor forma de se passar a conhecer uma ferramenta previamente desconhecida
seja instalando-a, e em seguida rodando um simples exemplo para test-la e familiarizar-se com
o que est por vir.
exatamente o que ser feito.
Instao
O Linux , decididamente, a plataforma ideal para este tipo de desenvolvimento e a que ns
recomendamos. No obstante, usurios de Windows podem seguir com o curso, assim como
os de Mac OS X. Apenas a etapa de instalao dever diferir do que est apresentado no curso
(Devido indisponibilidade de recursos, a tarefa de instalao ser deixada por conta do usurio).
Linux
Talvez at excessivamente simples, para se instalar o PyGTK nas distribuies Debian e derivados (tais como Ubuntu), basta instalar o pacote python-gtk2:

apt-get install python-gtk2


Isto ir instalar as bibliotecas necessrias. Caso seja solicitado para instalar pacotes dependentes, aceite.
Caso esteja usando outra distribuio, procure um pacote com este nome ou pygtk.

17

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

3.3 Conferindo a instalao


OK, tecnicamente estamos prontos para seguir em frente e aprendermos os conceitos. Mas
primeiro vamos verificar se a etapa de instalao realmente foi concluda com xito.
Crie um arquivo com o seguinte cdigo usando seu editor predileto:

import pygtk
import gtk

# Teste inicial

class Janela:
def __init__ (self):
self.janela = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.janela.show()
def main (self):
gtk.main()

if __name__ == "__main__":
janela = Janela()
janela.main()
Salve-o como "testando123.py"e execute-o (python testando123.py).
Enfrentou algum problema? Envie sua dvida ao frum! No ser possvel prosseguir com o
curso se este exemplo no funcionar.
No se preocupe com o cdigo, iremos detalh-lo mais adiante.
Perceba que este exemplo apenas exibe uma janela vazia. Nem mesmo o boto de fech-la
funciona. Veremos os motivos mais adiante.

18

Captulo 4

Lio 2 - Apresentando Widgets,


Signals e Callbacks
4.1 Conceitos bsicos
Antes de prosseguirmos com os exemplos, iremos dar uma breve olhada nos conceitos que
sero explorados. Estes so de crucial importncia para o entendimento pleno da matria. Usurios que no possuem experincia prvia com GTK+: leiam esta pgina atenciosamente.
Widgets
Um conceito extremamente simples; derivado de window gadets (apetrechos de janela), o
termo pode representar qualquer elemento de uma janela, tais como botes, barras de rolagem,
menus dropdown, campo de texto, barra de ttulo, barra de ferramentas e qualquer outra parafernlia que possa estar contida em uma janela. Em suma, tudo representado um widget.

Sinais
O GTK+ um chamado event-driven toolkit, significando que uma vez que se atinge o gtk.main(),
o processo adormece at que um evento ocorra e o controle seja redirecionado para a funo
correspondente. Este conceito denominado sinal (entretanto este conceito meramente semelhante aos signals Unix, a implementao bastante diferente). Quando ocorre um evento, como
o apertar de um boto, o widget ir emitir um sinal. Os sinais variam de widget para widget. Por
exemplo, o boto herda sinais de vrias classes:
gobject.GObject: "activate", "clicked", "enter", "leave", "pressed"e "released";
gtk.Object: "destroy";
gtk.Widget: "accel-closures-changed", "button-press-event", "button-release-event", "canactivate-accel", "child-notify", dentre muitas, muitas outras;
19

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

gtk.Container: "add", "check-resize", "remove", "set-focus-child".


Para o exemplo do boto, a lista completa de sinais pode ser encontrada em:
http://www.pygtk.org/docs/pygtk/class-gtkbutton.html#signal-prototypes-gtkbutton.
Percebe-se que a quantidade possvel de sinais imensa para um dado widget, e neste curso
iremos ver apenas os signals mais freqentemente utilizados.
Callback
Quando um sinal ocorre, uma funo callback pode ser acionada. Esta funo pode alterar
a interface, abrir uma janela popup, fechar o programa, conectar a um banco de dados, enfim:
o elo entre os widgets e o resto do programa. Como, ento, associar uma funo callback a um
signal? Para tal, os objetos em GTK possuem a funo connect:

handler_id = object.connect (name, func, func_data)


Nesta linha, object a instncia do GtkWidget que estar emitindo o sinal, e o primeiro argumento (name) indica o nome do sinal que ir acionar o callback (por exemplo "clicked"ou "destroy"). O segundo argumento (func) indica a funo (callback) que dever ser acionada. Repare
que o argumento o *objeto* da funo, e no o seu nome. No terceiro argumento, esto os
dados que sero repassados para a funo.
Portanto o callback dever ter o seguinte cabealho:

def callback_func (widget, callback_data)


O primeiro parmetro ser um ponteiro para a widget que emitiu o sinal, e o segundo parmetro um ponteiro para os dados definidos na chamada do connect.
Naturalmente, se a funo callback for definida em um mtodo, sua forma geral ser:

def callback_func_method (self, widget, callback_data)


Onde self representa a instncia do object acionando o mtodo.
(Existem excees quanto aos seus argumentos, mas de forma geral sero estes.)
Juntos, estes dois conceitos (signals e callbacks) formam boa parte dos fundamentos por trs
do GTK+.
Eventos
Alm dos sinais, existem tambm eventos, que refletem o mecanismo de eventos do X. So
muito similares a sinais, no sentido que callbacks tambm podem ser associados a estes. Refletem eventos tais como o requisitado fechamento de um programa, ou o clique do mouse (ou
duplo-, triplo-clique). No entanto, o cabealho de suas funes callback um pouco diferente:

def callback_func (widget, event, callback_data)


ou, no caso de uma funo callback definida em um mtodo:

def callback_func_method (self, widget, event, callback_data)


20

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Como fazer para conectar uma funo callback a um evento? Usando connect:

handler_id = object.connect (name, func)


Por exemplo, para um boto pode-se definir o evento da seguinte forma:

handler_id = botao.connect ("button_press_event", button_click_event)


No momento do evento, isto iria invocar a seguinte funo:

button_click_event (widget, event, callback_data)


O valor que esta funo retorna indica se o evento dever ser propagado pelo mecanismo
de gerenciamento de eventos do GTK+. Se retornar True, significa que o evento j foi tratado e
no dever propagar (isto , se houver mais de um callback associado a um evento). Se retornar
False, ento o evento ser propagado.
Se isto ainda est um pouco nebuloso, no se preocupe. Exemplos tornaro os conceitos
bem mais claros.
Desconectando callbacks
claro, tambm possvel desassociar um callback de um sinal ou um evento. O comando a
ser usado o seguinte:

object.disconnect (handler_id)

4.2 Um exemplo prtico


Agora que temos um embasamento terico podemos partir para exemplos.
Crie um arquivo com o nome botao1.py com o seguinte contedo:

#!/usr/bin/env python
# -*- coding: latin-1 -*import pygtk
import gtk
class Janela:
def __init__ (self):
""" Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
Isto feito atravs da gerao de uma instncia da classe
Window. """
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
""" Ajustamos alguns parmetros referentes janela:
- Ajusta o espaamento da borda para 10 (espao entre
borda e os widgets)
- Seta o ttulo da janela
21

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

- Altera o tamanho da janela


"""
self.janela.set_border_width (10)
self.janela.set_title ("Pythonizando GTK+")
self.janela.resize (300, 100)
""" Associa o callback self.delete_event ao evento
delete_event. Caso isso no fosse feito, o programa
continuaria sua execuo mesmo aps o fechamento da
janela """
self.janela.connect ("delete_event", self.delete_event)
""" Em seguida cria-se um boto (perceba que a isntncia de
uma classe. """
self.botao = gtk.Button ("Hey there")
""" IMPORTANTSSIMO: (quase) todo elemento deve ser
explicitamente exibido para que aparea na tela. """
self.botao.show ()
""" Adiciona o boto janela. Para adicionar mais elementos
ser necessrio criar um container, como veremos adiante """
self.janela.add (self.botao)
""" Exibe a janela (e consequentemente tudo contido nela). """
self.janela.show ()
def delete_event (self, widget, event):
gtk.main_quit()
return False
def main (self):
gtk.main()
if __name__ == "__main__":
janela = Janela()
janela.main()
O resultado ser algo assim:

A maior parte do cdigo bastante intuitiva; a criao da janela, atribuio de parmetros, criao do boto. H dois elementos importantes neste exemplo: o callback e as chamadas a show().
22

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

O mtodo show() causa uma widget a ser exibida assim que possvel. Antes de se chamar
este mtodo a widget no ser mostrada! Naturalmente, para que uma widget seja visualizada,
necessrio tambm que todos os contineres da widget tambm sejam explicitamente mostrados.
Quando um continer "toplevel"(que contm outros widgets) mostrado, este imediatamente
mapeado e exibido na tela, assim como todos os widgets contidos dentro deste que j estejam
exibidos. por este motivo que a ordem de chamada deve comear das widgets internas at
chegar nas widgets externas; caso contrrio o usurio ir ver a atualizao dos componentes
dependendo da complexidade grfica do GUI.
Outro aspecto importante do exemplo o callback usado para o fechamento do programa.
O evento "delete_event" chamado quando o sistema operacional recebe uma solicitao de fechamento do programa. Isto pode ocorrer quando o usurio clica no X para fechar, ou pelo
gerenciador de tarefas. Em todo caso, se no tratarmos este evento a widget em questo (no
caso a janela em si) ser finalizada, no entanto o gtk.main() continuar sua execuo (Tente isto:
remova o self.janela.connect e veja o que ocorre depois de fechada a janela). Por esse motivo
necessrio explicitamente executar gtk.main_quit(). O dado passado pelo delete_event (no quarto
parmetro da funo callback) None e portanto ignorado pela funo callback.
Voc consegue ver a utilidade disto? Nem sempre que o usurio fecha uma janela ele necessariamente teve tal inteno. O browser Firefox confirma o fechamento da janela se mais de uma
aba estiver aberta. O OpenOffice pergunta se deseja salvar o documento antes de fechar. este
evento o responsvel por essas aes.

23

Captulo 5

Lio 3 - Widgets elementares


5.1 Empacotando widgets
At o momento trabalhamos com apenas uma widget na janela principal. Como fazer para
agrup-las?
H vrias formas de faz-lo; a mais comum delas so caixas (boxes).
Boxes
Boxes so contineres transparentes nos quais podem ser empacotados outras widgets.
Pode-se usar tanto o HBox (horizontal) quanto o VBox (vertical). Ao empacotar elementos no
HBox eles podem ser inseridos da esquerda para a direita ou da direita para a esquerda, dependendo da forma como sejam criados. comum usar uma combinao de boxes (boxes dentro de
boxes) para criar o efeito desejado.
Como de se esperar, para criar um HBox basta gerar uma instncia de gtk.HBox(). Para
adicionar elementos a um box, usa-se o mtodo pack_start() e pack_end(), onde o primeiro insere da esquerda para a direita e o ltimo da direita para a esquerda. Boxes podem agrupar tanto
widgets quanto outros boxes.
Vale frisar que botes so contineres por si s, mas normalmente usa-se apenas um label
dentro do boto.
Como cri-los?
O cabealho da HBox() est definido da seguinte forma:

gtk.HBox (homogeneous = False, spacing = 0)


Se o primeiro parmetro for True, isto garantir que todos os elementos tenham exatamente a
mesma largura. O segundo parmetro especifica o espaamento entre os elementos.
Alm disso, a forma como se agrupa os elementos tambm altera a aparncia geral do layout:

box.pack_start(child, expand=True, fill=True, padding=0)

24

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Box o container onde o widget ser empacotado e o parmetro child deve ser o objeto do widget
a ser empacotado. Os outros parmetros controlam como os widgets inseridos se adaptaro ao
box (ou vice-versa):
Expand define se o objeto se ajustar para ocupar todo o espao disponvel no widget (True)
ou se o box se reduzir ao tamanho dos widgets (False). Se isto for False, possvel manter
todos os widgets alinhados no canto direito ou esquerdo do box;
O parmetro fill somente tem efeito se o expand for false; neste caso, ele controla se o espao remanescente no box dever ser alocado como espaamento entre os widgets (False)
ou se os widgets recebero o espao remanescente (True).
Finalmente padding o espaamento que ser adicionado a ambos os lados do widget.
Qual a diferena entre padding (fornecido no pack_start() ou pack_end()) e spacing (fornecido
no HBox() ou VBox())? O spacing o espao adicionado entre os elementos, e o padding o
espao adicionado a ambos os lados de um elemento.
Toda essa teoria tambm se aplica ao VBox, invertendo-se os eixos.
Exemplificando
Observe o exemplo a seguir, botao2.py:

#!/usr/bin/env python
# -*- coding: latin-1 -*import pygtk
import gtk
class Janela:
def __init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
# Ajustamos alguns parmetros referentes janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botes 2")
self.janela.resize (300, 50)
# Em seguida cria-se os botes:
self.botao1 = gtk.Button ("Hey there")
self.botao2 = gtk.Button ("Au revoir", gtk.STOCK_QUIT)
# Associa o callback self.delete_event ao evento
# delete_event.
self.janela.connect ("delete_event", self.delete_event)
# Especificamos o argumento data como None
self.botao1.connect ("clicked", self.button_click, None)
25

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

self.botao2.connect ("clicked", self.delete_event, None)


# Exibe-os
self.botao1.show ()
self.botao2.show ()
# Cria-se um HBox homogneo (todos elementos ocupam o mesmo
# espao) com espaamento 10 entre os elementos.
self.hbox = gtk.HBox (True, 10)
# Empacota os botes no HBox
self.hbox.pack_start (self.botao1)
self.hbox.pack_start (self.botao2)
# Adiciona o boto janela. Para adicionar mais elementos
# ser necessrio criar um continer, como veremos adiante
self.janela.add (self.hbox)
# Exibe o hbox
self.hbox.show ()
# Exibe a janela
self.janela.show ()
def delete_event (self, widget, event):
gtk.main_quit()
def button_click (self, widget, event):
print "Hullo"
def main (self):
gtk.main()
if __name__ == "__main__":
janela = Janela()
janela.main()
O resultado deve ser o seguinte:

Obviamente pode-se ir muito alm disso, encapsulando vrios boxes e criando um layout extremamente flexvel.

26

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

5.2 O widget do boto


Vimos no exemplo anterior que botes podem ser customizados com parmetros adicionais.
J sabemos praticamente tudo sobre botes, mas h alguns truques dos quais devemos estar
cientes.
A sintaxe bsica para criar um boto :

button = gtk.Button(label=None, stock=None)


O primeiro parmetro especifica o texto a ser exibido (opcional) e o stock pode ser uma de vrias
constantes pr-definidas com padres de botes (tambm opcional). O stock (STOCK_QUIT)
usado no exemplo da lio anterior um boto tipicamente usado para sair de programas. A
variedade completa est disponvel em http://www.pygtk.org/docs/pygtk/gtk-stock-items.html.
Dica: Sendo a usabilidade um aspecto muito importante nos aplicativos de atualmente, comum que programas suportem atalhos de teclado em vez de necessitar que se use o mouse. Por
isto, para sublinhar uma letra do label, basta prefix-la com _. Isto se aplica a todos os botes
vistos nesta pgina. Assim, ao apertar Alt+(letra sublinhada), seria como se o usurio clicasse no
boto.
Customizando o visual
H de se convir que as possibilidades so bastantes limitadas se no se pode ao menos criar
um boto com um cone customizado; tem de haver uma forma de se criar um boto diferenciado;
e de fato existe. Analise o seguinte exemplo, botao3.py:

#!/usr/bin/env python
# -*- coding: latin-1 -*import pygtk
import gtk
class Janela:
def __init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
# Ajustamos alguns parmetros referentes janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botes 3")
self.janela.resize (100, 50)
# Assegura-se que a janela ser fechada corretamente.
# (Lembre-se de funes lambda em Python!)
self.janela.connect("destroy", lambda wid: gtk.main_quit())
self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit())

27

CDTC

Centro de Difuso de Tecnologia e Conhecimento

# Em seguida cria-se o boto (perceba a ausncia do label)


self.botao = gtk.Button ()
# Cria-se o box do boto...
self.box = self.xpm_label_box ("tartan.xpm", u"faa algo!")
# E adiciona o HBox com os contedos do boto
self.botao.add (self.box)
# Exibe-os
self.box.show()
self.botao.show ()
# Adiciona o boto janela. Para adicionar mais elementos
# ser necessrio criar um container, como veremos adiante
self.janela.add (self.botao)
# Exibe o hbox
self.box.show ()
# Exibe a janela
self.janela.show ()
def xpm_label_box (self, xpm_arquivo, label_texto):
# Cria-se o HBox no-homogneo (o cone menor que o label)
# e sem espaamento.
box = gtk.HBox (False, 0)
# Adiciona uma pequena borda como em um boto
box.set_border_width (2)
# NOVIDADE: cria a imagem
imagem = gtk.Image()
imagem.set_from_file (xpm_arquivo)
# Cria o label
label = gtk.Label (label_texto)
# Adiciona a imagem e o label ao box
box.pack_start (imagem, False, False, 3)
box.pack_start (label, False, False, 3)
# Mostra tudo
imagem.show()
label.show()
return box

28

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

def main (self):


gtk.main()
if __name__ == "__main__":
janela = Janela()
janela.main()

Preste ateno ao exemplo e perceber que no possvel criar um boto com um pixmap
diferenciado "nativamente", na realidade criamos um HBox no qual esto contidos o pixmap e
o label. O mtodo que usamos, xpm_label_box, poderia com facilidade ser usado em qualquer
outro elemento que possa ser um continer.
A propsito, para se criar o pixmap podemos usar uma diversidade de programas, inclusive o
open-source GIMP.
Outros botes
Outras formas de botes so freqentemente vistas, como toggle buttons (que possuem um
relevo para indicar se esto selecionados ou no), checkboxes (uma pequena caixa que pode
ser marcada ou desmarcada) e radio buttons (conjunto de botes dos quais apenas um pode ser
selecionado atravs de pequenas bolas). Na ausncia de uma traduo melhor irei me referir aos
nomes originais, em ingls.
Toggle buttons
Toggle buttons so derivados de botes normais e so muito similares, exceto o fato de que
sempre estaro em um de dois estados (pressionado ou no), alterados atravs de um clique.
Seu estado se altera a cada clique. Estes botes so a base para check buttons e radio buttons,
com muitas similaridades na implementao.
Como criar um?

botao = gtk.ToggleButton(label=None)
Cada widget deste tipo possui uma funo get_active() que retorna se o boto est pressionado
ou no; o sinal que indica que o estado de um boto foi alterado o "toggled"; juntando as
duas peas do quebra-cabea, rapidamente descobrimos como trabalhar com as mudanas de
estados:

def toggle_button_callback (widget, data):


if (widget.get_active()):
# boto est pressionado
else:
# boto no est pressionado
29

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

A funo get_active() pode ser usada sempre que se precisar obter o estado do boto, sendo
que esta retornar True (pressionado) ou False (no-pressionado).
E como alterar o estado do boto manualmente? Usa-se o seguinte mtodo:

botao.set_active(active)
Onde active pode ser True (pressionado) ou False (no-pressionado). O valor inicial (quando o
boto gerado) False.
Perceba que quando esta funo for chamada, os sinais "clicked"e "toggled"sero emitidos
pelo boto!
Check buttons
Como j foi mencionado, seu funcionamento muito parecido com toggle buttons, e de fato,
so simplesmente toggle buttons com uma aparncia diferente, j que os labels ficam na lateral
da "caixinha"que o usurio marca. A criao feita da seguinte forma:

botao = gtk.CheckButton(label=None)
O callback de verificao de estado (get_active()) pode ser feito da mesma forma que nos toggle
buttons, assim como o ajuste de estado (set_active()).
Radio buttons
Radio buttons so similares aos check buttons, mas possuem a diferenciao de serem agrupados de tal forma que apenas um pode estar selecionado por vez. Isto bom quando a lista de
opes razoavelmente pequena.
A criao feita com o seguinte comando:

botao = gtk.RadioButton (group=None, label=None)


Perceba a existncia de um argumento extra. Radio buttons requerem de um grupo para funcionar. A primeira chamada para gtk.RadioButton() dever passar como argumento de group None,
e um novo grupo de radio buttons ser criado com o novo boto.
Para adicionar mais radio buttons para o grupo, passe a referncia para um radio button nas
chamadas subseqentes a gtk.RadioButton().
tambm uma boa idia explicitar qual boto dever estar apertado inicialmente com o comando

button.set_active(is_active)
Isto funciona da mesma forma como foi descrito acima. Uma vez que radio buttons esto agrupados, apenas um do grupo pode estar ativo. Por este motivo, se o usurio clicar em um, depois em
30

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

outro boto de dado grupo, o primeiro radio button ir emitir o sinal "toggled"(j que foi desativado)
e o segundo boto tambm ir emitir o sinal "toggled"(j que acabara de ser pressionado).
Recapitulando
No intuito de fixar e exemplificar o que foi visto acima, preste ateno no exemplo botao4.py.

#!/usr/bin/env python
# -*- coding: latin-1 -*import pygtk
import gtk
class Janela:
# Funo callback que monitora o estado dos botes
def callback (self, widget, data=None):
print "Botao %s foi %s." % (data, ("desselecionado",
s "selecionado")[widget.get_active()])
def __init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
# Ajustamos alguns parmetros referentes janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botes + botes")
self.janela.resize (200, 400)
# Assegura-se que a janela ser fechada corretamente.
# (Lembre-se de funes lambda em Python!)
self.janela.connect("destroy", lambda wid: gtk.main_quit())
self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit())
vbox = gtk.VBox (True, 2)
toggle1 = gtk.ToggleButton("Toggle button 1")
toggle1.connect ("toggled", self.callback, "Toggle button 1")
toggle2 = gtk.ToggleButton("Toggle button 2")
toggle2.connect ("toggled", self.callback, "Toggle button 2")
vbox.pack_start (toggle1, False, False, 2)
toggle1.show()
vbox.pack_start (toggle2, False, False, 2)
toggle2.show()
checkbox1 = gtk.CheckButton("Checkbox 1")
checkbox1.connect ("toggled", self.callback, "Checkbox 1")
checkbox2 = gtk.CheckButton("Checkbox 2")
checkbox2.connect ("toggled", self.callback, "Checkbox 2")

31

CDTC

Centro de Difuso de Tecnologia e Conhecimento

vbox.pack_start (checkbox1, False, False, 2)


checkbox1.show()
vbox.pack_start (checkbox2, False, False, 2)
checkbox2.show()
radio1 = gtk.RadioButton(None, "Radio button 1")
radio1.connect ("toggled", self.callback, "Radio button 1")
radio2 = gtk.RadioButton(radio1, "Radio button 2")
radio2.connect ("toggled", self.callback, "Radio button 2")
radio3 = gtk.RadioButton(radio2, "Radio button 3")
radio3.connect ("toggled", self.callback, "Radio button 3")
vbox.pack_start (radio1, False, False, 2)
radio1.show()
vbox.pack_start (radio2, False, False, 2)
radio2.show()
vbox.pack_start (radio3, False, False, 2)
radio3.show()
# E adiciona o HBox com os contedos do boto
self.janela.add (vbox)
# Exibe-os
vbox.show()
# Exibe a janela
self.janela.show ()
def main (self):
gtk.main()
if __name__ == "__main__":
janela = Janela()
janela.main()
Screenshot do programa em ao:

32

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Mensagens so emitidas no terminal a cada alterao nos botes.


Repare como a criao do radio button diferente dos demais, assim como o seu funcionamento.

33

Captulo 6

Lio 4 - Widgets miscelneas 1


6.1 Adjustments
Um elemento muito frequente em interfaces com usurios o "slider", uma barra de rolagem
atravs da qual o usurio pode escolher uma faixa de valores. Eis um exemplo:

O GTK+ obviamente suporta tais widgets, mas primeiro devemos entender um pouco sobre a
teoria por trs de seu funcionamento.
Adjustments
Uma aplicao necessita reagir s aes de usurios nestes widgets; isto poderia ser feito
atravs de um sinal emitido pela widget quando houvesse uma mudana no seu valor, no qual
a widget transmite tambm o novo valor para a funo responsvel. Mas e se quisssemos associar os ajustes de vrias widgets, de tal forma, que mudar o valor em uma widget alteraria
outra? Uma aplicao prtica para isto seria conectar as barras de rolagem de tal forma a selecionar o contedo a ser visualizado, por exemplo, de uma imagem(Ser isso um pressgio?). Se
cada widget de ajuste tivesse de emitir um sinal a cada mudana de valor, o programador teria
de escrever gerenciadores de sinais para transmitir a mudana de valor de uma widget para outra.
O GTK+ nos auxilia atravs do objeto Adjustment, que no uma widget, mas uma forma
atravs da qual widgets podem transmitir informaes sobre ajustes de uma forma abstrata e
flexvel. Alm de guardarem parmetros de configurao e valores de widgets (ou vrias delas),
Adjustments podem emitir sinais, assim como widgets convencionais, e isso pode ser usado para
propagar informaes entre vrias widgets separadas.
Voc j conhece bem esse tipo de widget; so barras de progresso, janelas com barra de
rolagem, dentre outros.
Criando um Adjustment
A sintaxe simples:
34

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

adjustment = gtk.Adjustment(value=0, lower=0, upper=0, step_incr=0, page_incr=0, page_size=0)


O parmetro value indica o valor inicial a ser atribudo widget. Lower e upper so o menor e
maior valores que podem ser assumidos pelo widget. Step_incr define o intervalo entre os ajustes, page_incr define o maior intervalo entre estes. Finalmente o page_size o parmetro que
contm a rea visvel no caso de uma widget qual se aplique.
Os widgets ajustveis podem ser divididos naqueles que necessitam de uma unidade especfica (por exemplo pixels) e aqueles que usam nmeros arbitrrios. Alguns widgets que usam
nmeros arbitrrios incluem a barra de rolagem e a barra de progresso. Estas podem ser ajustadas pelo mouse ou pelo teclado, e a faixa de valores pode ser definida no ajuste. Por padro,
manipular tal widget apenas altera o valor de seu Adjustment.
O outro grupo inclui o widget de texto e a janela com barra de rolagem. Estes necessitam valores em pixels para seus Adjustments. Alguns widgets que podem ser ajustados indiretamente
usando barras de rolagem, a exemplo do ScrolledWindow que veremos adiante.
Adjustments podem tambm ser manipulados manualmente. Para alterar o valor de um objeto
Adjustment, usamos

adjustment.set_value(value)
Como j dissemos, Adjustments so capazes de emitir sinais (por serem derivados da classe
Object, assim como outros widgets) e por este motivo mudanas se propagam automaticamente
quando por exemplo uma barra de rolagem conectada a outra widget alterada; todas widgets
ajustveis se conectam atravs do sinal value_changed.

6.2 Widgets de faixa de valores


Com um pouco de bagagem sobre Adjustments, podemos voltar ao tpico inicial da lio.
Como se pode imaginar, todas as widgets de faixa de valores so associadas a um objeto
Adjustment, atravs da qual estas calculam as dimenses da barra de rolagem.
Barra de rolagem
So os widgets mais simples desta categoria e uma das quais mais lidamos. So apropriadas para mudar aspectos de outras widgets, como uma lista, uma caixa de texto ou um viewport.
Para outras funcionalidades (como escolher um valor especfico) mais recomendvel usar widgets de escala, que so mais amigveis e possuem mais funcionalidades.
Podemos cri-las atravs do seguinte comando (horizontal ou vertical):

hscroll = gtk.HSrollbar (adjustment=None)


vscroll = gtk.VSrollbar (adjustment=None)

35

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

O parmetro pode ser um adjustment criado pela funo mostrada na seo anterior. Na
omisso deste ser criado um adjustment automaticamente, que pode subseqentemente ser
obtido atravs de funes auxiliares.
Widget de escala
Idntico ao exemplo dado no incio da lio, widgets Scale permitem que o usurio manipule
um valor em uma faixa especfica. Pode ser usado, por exemplo, para alterar o zoom de uma
pgina ou o contraste de uma imagem.
Estes widgets possuem 2 tipos: 1 para widgets horizontais outro para widgets verticais (a
verso horizontal mais comum). Funcionam exatamente da mesma maneira. Para cri-los:

vertical_scale = gtk.VScale (adjustment=None)


horizontal_scale = gtk.HScale (adjustment=None)
V o parmetro adjustment? atravs deste que se pode "linkar"widgets a um adjustment em
comum. Caso seja omitido, o adjustment ser criado pela funo com todos os valores ajustados
em 0.0, o que no muito til. Como o page_size pode afetar o valor mximo da widget (alm do
especificado pelo parmetro upper), recomendado que se ajuste o page_size em 0.0 para que
o valor upper coincida com o maior valor que o usurio possa selecionar.
Opes
Algumas widgets de escala exibem o valor escolhido ao seu lado; isto pode ser feito atravs
da seguinte funo:

scale.set_draw_value (draw_value)
Onde draw_value pode ser True ou False. O nmero de casas decimais exibido pode ser ajustado
atravs de:

scale.set_digits (digits) (o limite 13)


Para definir a posio relativa onde o valor ser representado, usa-se:

scale.set_value_pos (pos)
Onde o argumento pos pode ser qualquer um de POS_LEFT, POS_RIGHT, POS_TOP ou
POS_BOTTOM.
Poltica de atualizao
Como voc j sabe, o sinal "value_changed" emitido quando o valor alterado. Mas quando
exatamente isso? A qualquer mudana? Apenas quando o usurio pra de mover a barra da
widget? H 3 polticas de atualizao:

36

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

UPDATE_CONTINUOUS: Emite o sinal value_changed continuamente, mesmo que a barra


seja movida muito pouco;
UPDATE_DISCONTINUOUS: Emite o sinal value_changed apenas quando o valor da widget no est em movimento e o usurio solta o boto do mouse;
UPDATE_DELAYED: Emite o sinal value_changed se o usurio soltar o boto do mouse, ou
se a barra ficar parada por um curto instante.
Para ajustar uma destas polticas faa o seguinte:

range.set_update_policy (policy)
Obtendo e usando um adjustment
s vezes o adjustment no criado explicitamente, sendo isto feito atravs da criao de uma
widget que o necessita. Nestes casos podemos obter o adjustmente atravs de:

adjustment = range.get_adjustment()
Da mesma forma, para configurar uma widget para usar outro adjustment usamos:

range.set_adjustment(adjustment)
(Perceba que o set_adjustment() no surtir efeito se o adjustment for o mesmo em uso pela
widget, mesmo que seus valores tenham sido alterados. Para tal seria adequado emitir o sinal
"changed"atravs de adjustment.emit("changed").)

6.3 Labels
Labels (rtulos) esto entre os widgets mais simples, no entanto so um dos mais frequentemente usados. Simplesmente exibem texto que no editvel pelo usurio, como o usado em
um formulrio para indicar os campos correspondentes. Para cri-los:

label = gtk.Label (str)


Onde str deve conter o valor inicial a ser assumido pelo label. Para alterar este texto posteriormente sua criao:

label.set_text (str)
Da mesma forma pode-se obter o texto j contido em um label:

str = label.get_text ()
Alm disso, estas widgets podem exibir texto ao longo de vrias linhas quando a str os contm.
possvel tambm fazer com que a widget automaticamente acrescente as quebras de linha:
37

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

label.set_line_wrap (wrap)
Onde o parmetro wrap pode ser True ou False.
Muitas outras opes so suportadas; como sempre recomenda-se referir documentao
original:
http://www.pygtk.org/docs/pygtk/class-gtklabel.html.

6.4 reas com barras de rolagem


Ainda no tpico de adjustments e widgets com faixa de valores, um dos widgets mais teis
que utilizam esse recurso o ScrolledWindow. Consiste em uma rea (um viewport) sendo que
apenas uma parte pode ser exibida. Barras de rolagem nas laterais permitem que o usurio
selecione a rea a ser visualizada. (Podem ser omitidas caso a rea possa ser exibida na sua
ntegra, tanto no eixo horizontal quanto no eixo vertical.) O melhor de tudo o fato de tudo isto
ser uma nica widget! Veja s:

scrolled_window = gtk.ScrolledWindow(hadjustment=None, vadjustment=None)


Os dois parmetros so os adjustments a serem usados no sentido horizontal e vertical da widget. Usualmente no necessrio especific-los.
Para definir quando as barras de rolagem devero ser exibidas, usa-se

scrolled_window.set_policy(hscrollbar_policy, vscrollbar_policy)
Onde cada um desses valores pode ser POLICY_AUTOMATIC (determina automaticamente se a
barra de rolagem dever estar disponvel) ou POLICY_ALWAYS (sempre estar disponvel).
Para adicionar o widget que se deseja exibir ao ScrolledWindow:

scrolled_window.add_with_viewport(child)

6.5 Exemplo
Temos a seguir um simples exemplo (misc1.py) que usa os conceitos aprendidos nesta lio.
O exemplo no particularmente til, mas ilustra bem os conceitos aprendidos.

#!/usr/bin/env python# -*- coding: latin-1 -*-import pygtk


import gtk

38

CDTC

Centro de Difuso de Tecnologia e Conhecimento

classJanela:
def__init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)

# Ajustamos alguns parmetros referentes janela:


self.janela.set_border_width (10)
self.janela.set_title (u"Widgets miscelneos")
self.janela.resize (200, 400)

# Assegura-se que a janela ser fechada corretamente.


# (Lembre-se de funes lambda em Python!)
self.janela.connect("destroy", lambda wid: gtk.main_quit())
self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit())

# Conteiner de todos os elementos


vbox = gtk.VBox (False, 2)

# Widgets de faixa de valores


hadjustment = gtk.Adjustment()
vadjustment = gtk.Adjustment()

# Cria os widgets de escala usando o recm-criado adjustment


hscale = gtk.HScale(hadjustment)
vscale = gtk.HScale(vadjustment)
39

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

hscale.show()
vscale.show()

# Widgets label
hlabel = gtk.Label("Ajuste horizontal:")
vlabel = gtk.Label("Ajuste vertical:")
hlabel.show()
vlabel.show()

# Imagem que sera encapsulada


image = gtk.Image()
image.set_from_file ("fall_wallpaper_10.jpg")
image.show()

# Continer da imagem
scrolled_window = gtk.ScrolledWindow(hadjustment, vadjustment)
scrolled_window.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scrolled_window.add_with_viewport(image)
scrolled_window.show()

# Acrescenta todos os elementos ao VBox


vbox.pack_start (hlabel, False, False, 2)
vbox.pack_start (hscale, False, False, 2)
vbox.pack_start (vlabel, False, False, 2)
40

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

vbox.pack_start (vscale, False, False, 2)


vbox.pack_start (scrolled_window, True, True, 2)

# E adiciona o HBox com os contedos do boto


self.janela.add (vbox)

# Exibe-os
vbox.show()

# Exibe a janela
self.janela.show ()

defmain (self):
gtk.main()

if __name__ == "__main__":
janela = Janela()
janela.main(
Screenshot:

41

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

42

Brasil/DF

Captulo 7

Lio 5 - Widgets miscelneas 2


7.1 Barras de progresso
Iremos nesta lio continuar a explorao pelas widgets do GTK+. Todas estas so vistas
com bastante freqncia.
Barras de progresso
Todo usurio as conhece; so usadas para representar o processo de uma operao. Como
tudo no GTK+, so fceis de se criar e manipular:

progressbar = gtk.ProgressBar(adjustment=None)
O parmetro adjustment (opcional) pode receber um adjustment criado previamente. Reveja a
lio anterior se necessrio.
Para alterar o valor exibido pela barra de status, usa-se

progressbar.set_fraction(fraction)
Onde fraction um nmero entre 0 e 1, representando a percentagem da barra que dever estar
preenchida.
tambm possvel que o preenchimento ocorra da direita para esquerda (ou outros), em vez
de ser da esquerda para a direita:

progressgar.set_orientation(orientation)
orientation pode assumir um dos seguintes valores:
PROGRESS_LEFT_TO_RIGHT: da esquerda para a direita;
PROGRESS_RIGHT_TO_LEFT: da direita para a esquerda;
PROGRESS_BOTTOM_TO_TOP: de baixo para cima;

43

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

PROGRESS_TOP_TO_BOTTOM: de cima para baixo.


Alm de poder exibir uma frao, a barra pode tambm indicar que um processo est ocorrendo sem precisar o quanto da operao foi concludo. Para isso, usa-se pulse:

progressbar.pulse()
Isto exibe uma barra oscilante. E para configurar o tamanho desta barra, usa-se:

progressbar.set_pulse_step (fraction)
Onde fraction novamente um valor entre 0 e 1.
Para configurar e obter um texto a ser exibido na barra, temos os seguintes comandos: p

rogressbar.set_text (text)
text = progressbar.get_text ()

7.2 Dialogs
O widget Dialog tambm conhecido como pop-up por alguns. Consiste em uma janela com
alguns elementos empacotados (um vbox (chamado vbox) para contedo e um hbox (chamado
action_area) para botes e aes que o usurio possa realizar). Sua criao bastante simples:

dialog = gtk.Dialog(title=None, parent=None, flags=0, buttons=None)


Onde title o ttulo do Dialog, parent a janela principal da aplicao e flags setam as vrias
opes de criao, dentre elas:

DIALOG_MODAL - Faz com que o usurio no possa manipular a janela principal, apenas
a que foi criada;
DIALOG_DESTROY_WITH_PARENT - Fora que o Dialog seja destrudo quando sua janela
principal for fechada;
DIALOG_NO_SEPARATOR - Omite o separador enter vbox e action_area.
Para adicionar elementos ao Dialog basta empacotar usando pack_start() ou pack_end() no
vbox ou action_area do Dialog. Por exemplo:

dialog.action_area.pack_start(button, True, True, 0)


dialog.vbox.pack_start(label, True, True, 0)
Podem ser manipulados como se fossem janelas (isto , callbacks para "destroy"funcionaro
normalmente, por exemplo).

44

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

7.3 Barras de status


So widgets relativamente simples que exibem uma mensagem por vez. Servem para auxiliar o usurio na interao com um programa; por exemplo, quando sobrepor o mouse sobre um
cone a barra de status pode comunicar a funcionalidade do boto. Ou ento informar sobre o
progresso de um processo.
Para que permita que vrias partes da aplicao utilizem a mesma barra de status, tem-se o
que se chama de identificadores de contexto, que identificam os diferentes "usurios". Ela tambm tem uma pilha que assegura que a mensagem a ser exibida sempre ser a que est no topo
da pilha. (Ou seja, seu funcionamento LIFO, last in first out).
Para criar uma barra de status:

statusbar = gtk.Statusbar()
Para requisitar-se um identificador de contexto, usa-se a seguinte funo, que recebe tambm
uma breve descrio do contexto:

context_id = statusbar.get_context_id (description)


Para inserir uma mensagem, deve-se especificar o id do contexto bem como o texto a ser exibido:

message_id = statusbar.push (context_id, message)


A remoo da ltima mensagem adicionada naquele contexto feita assim:

statusbar.pop (context_id)
E a remoo de uma mensagem especfica:

statusbar.remove (context_id, message_id)


Lembre-se que a mensagem a ser exibida sempre ser a ltima que foi adicionada (atravs de
push). Como se pode perceber, cada parte do programa pode interagir com a barra de status de
forma independente, j que ter seu prprio context_id.

7.4 Exemplo
Como de praxe, terminaremos esta lio de widgets com um exemplo sobre o que foi aprendido.

45

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Por motivos didticos foi usado um timeout, tpico que no ser visto neste curso, para
a atualizao automatizada da barra de progresso. No entanto basta saber que timer = gobject.timeout_add(interval, function, ...) ir executar a cada intervalo milisegundos a funo function. Para que se cancele a execuo de um timeout, usa-se gobject.source_remove (timer).
Ao cdigo, misc2.py:

#!/usr/bin/env python# -*- coding: latin-1 -*-import pygtk


import gtk
import gobject

defprogress_timeout (pbobj):
# Cria valor (valor atual + 1%)
valor = pbobj.progressbar.get_fraction() + 0.01
if valor > 1.0:
# Atingimos 100%, fechar popup
pbobj.dialog.destroy()
# Ao retornar "False" garantimos que progress_timeout cessar de ser
#chamadoreturn False

# Atualiza valor da barra de progresso


pbobj.progressbar.set_fraction(valor)

# Returna True para que o callback continue sendo executado.return True

classJanela:
defdestroy_popup (self, widget, context_id):
# Fechamento do popup
46

CDTC

Centro de Difuso de Tecnologia e Conhecimento

self.statusbar.pop(context_id)
gobject.source_remove (self.timer)

defbotao_popup (self, widget, dialog):


# Aborta operao do popup
dialog.destroy()

defpopup (self, data):


# Criao da janela pop-up (perceba a referncia janela que a criou)
self.dialog = gtk.Dialog ("Processando...", self.janela, gtk.DIALOG_MODAL)

# Adiciona-se um boto ao "action_area" (area inferior do pop-up)


button = gtk.Button ("Abortar!")
button.connect ("clicked", self.botao_popup, self.dialog)
button.show()

self.dialog.action_area.pack_start (button, True, True, 5)

# Adiciona-se uma barra de progresso ao "vbox" (area superior do pop-up)


self.progressbar = gtk.ProgressBar ()
self.progressbar.set_text ("Por favor aguarde...")
self.progressbar.show()

self.dialog.vbox.pack_start (self.progressbar, True, True, 5)


47

Brasil/DF

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

# Cria um timeout que atuailza periodicamente o status da barra de progresso


self.timer = gobject.timeout_add (100, progress_timeout, self)

# Atualiza a mensagem da barra de status na janela principal para indicar atividade


context_id = self.statusbar.get_context_id ("popup")
message_id = self.statusbar.push (context_id, "Processando...")

# Associa o fechamento da janela a dsetroy_popup# (para remover a mensagem da barra


#de status)
self.dialog.connect ("destroy", self.destroy_popup, context_id)

# Exibe o pop-up
self.dialog.show()

def__init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)

# Ajustamos alguns parmetros referentes janela:


self.janela.set_border_width (10)
self.janela.set_title (u"Widgets miscelneos")
self.janela.resize (200, 80)

48

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

# Assegura-se que a janela ser fechada corretamente.# (Lembre-se de funes lambda


# em Python!)
self.janela.connect("destroy", lambda wid: gtk.main_quit())
self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit())

# Continer de todos os elementos


vbox = gtk.VBox (False, 2)

# Cria o boto que iniciar a ao


button = gtk.Button (u"Faa algo!")
button.connect ("clicked", self.popup)
button.show()

# Cria a barra de status e adiciona uma mensagem inicial


self.statusbar = gtk.Statusbar()
context_id = self.statusbar.get_context_id ("main")
message_id = self.statusbar.push (context_id, "Em standby.")
self.statusbar.show()

# Insere os elementos recm-criados no vbox


vbox.pack_start (button, True, True, 2)
vbox.pack_end (self.statusbar, False, False, 0)

# E adiciona o HBox com os contedos do boto


49

CDTC

Centro de Difuso de Tecnologia e Conhecimento

self.janela.add (vbox)

# Exibe-os
vbox.show()

# Exibe a janela
self.janela.show ()

defmain (self):
gtk.main()

if __name__ == "__main__":
janela = Janela()
janela.main()
Screenshot do programa em execuo:

50

Brasil/DF

Captulo 8

Lio 6 - Widgets miscelneas 3


8.1 Menus
Em GTK+ existem vrias formas possveis de se criar menus. Neste curso iremos ver a forma
mais manual, por motivos didticos. Os outros mtodos abstraem parte do funcionamento o que
acaba sendo prejudicial para o aprendizado.
So 3 os widgets usados para se fazer uma barra de menus e submenus:

O item de menu, que o usurio clica para realizar a ao solicitada (por exemplo "Fechar");
O menu, que atua como continer para os itens de menu, e;
A barra de menus, que serve de continer para cada um dos menus.

Uma abstrao do termo item de menu deve ser feita, j que seu widget pode ser usado
tanto para criar os itens de menu que efetivamente realizam a ao solicitada pelo usurio (por
exemplo "Novo", "Recortar", "Colar"), quanto para os elementos na barra de menus (por exemplo
"Arquivo", "Editar").
Comeando pelo topo, criaremos a barra de menus:

menu_bar = gtk.MenuBar()

51

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Dispensando maiores explicaes, esta funo cria a barra de menus, que poder subseqentemente ser adicionada a outro continer.

menu = gtk.Menu()
Esta funo retorna uma referncia para um novo menu. No necessrio chamar a funo
show(), pois serve apenas de continer para os itens de menu.

menu_item = gtk.MenuItem(label=None)
Finalmente, o item de menu. Este recebe um rtulo (label), que ser interpretado por caracteres mnemnicos precedidos de "_". necessrio que se chame a funo show() pra que seja
exibido. No confunda item de menu com menu! O primeiro o boto associado a uma ao, e
o segundo um continer para itens de menu.
A adio de um item de menu ao menu feita atravs do comando append:

menu.append(menu_item)
E, finalmente, a associao de aes aos itens de menu feita de forma convencional:

menu_item.connect_object ("activate", menuitem_response, "menu_action")


OK, temos o menu pronto. Precisa-se de uma barra de menus:

menu_bar = gtk.MenuBar()
widget.add (menu_bar)
menu_bar.show()
No entanto, lembre-se que o menu em si no pode ser exibido; a exibio do mesmo ser
feita atravs de um item de menu, que ser ento adicionado barra de menus:

menu_item_arquivo = gtk.MenuItem("Arquivo")
menu_item_arquivo.show()
menu_item_arquivo.set_submenu(menu)
Caso se queira que o item fique alinhado direita, podemos usar o seguinte comando antes
de adicion-lo barra de menus:

menu_item.set_right_justified (right_justified)

52

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Finalmente, o adicionamos barra de menus, finalizando a construo:

menu_bar.append (menu_item_arquivo)
Afinal, no foi to difcil quanto possa parecer! Mas agora que voc j entende os elementos
de construo do menu, caso deseje automatizar este procedimento, possvei tanto escrever
funes auxiliares ou usar as formas embutidas no GTK+: ItemFactory ou UIManager. Desde
PyGTK 2.4, o uso do ItemFactory est depreciado, portanto deve-se usar o UIManager, que
constri o menu a partir de uma estrutura XML.

8.2 Entrada de texto


Um elemento crucial de interfaces deixado de fora at o momento o campo onde o usurio
pode entrar com contedo livre (texto). Em GTK+ um tal widget o Entry. Este permite criar um
campo simples, de apenas uma linha.

A sintaxe de criao a seguinte:

entry = gtk.Entry (max=0)


Onde max o limite de caracteres permitido, e o valor 0 indica a ausncia da limitao. Sua
alterao possvel aps a criao:

entry.set_max_length (max)
Da mesma forma possvel alterar o contedo (texto):

entry.set_text (text)
(Como a classe Entry derivada da classe Editable, aquela suporta algumas funes tais
como insert_text; a lista completa pode ser visualizada em http://www.pygtk.org/docs/pygtk/classgtkeditable.html).

entry.set_editable(editable)
entry.set_visibility(visible)
Estes comandos permitem, respectivamente, habilitar e desabilitar a edio de seu contedo
por parte do usurio (onde editable pode ser True ou False), e permitir ou no a visualizao do
contedo sendo digitado. Isto pode ser til em campos de senhas.
53

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

8.3 Spin buttons


Este tipo de boto pode ser usado pelo usurio para se escolher entre uma faixa de valores
numricos. Seu funcionamento rege em torno dos Adjustments; reveja a lio caso seja necessrio.

A criao do spin button feita assim:

spin_button = gtk.SpinButton(adjustment=None, climb_rate=0.0, digits=0)


O adjustment ser automaticamente criado caso seja omitido, e o que controla a faixa de
valores do widget. O climb rate indica a quantidade de acelerao que o boto tem ao ser pressionado (variando entre 0.0 e 1.0), e digits a quantidade de casas decimais que deve ser exibida.
possvel tambm alterar esses valores:

spin_button.configure (adjustment, climb_rate, digits)


que obedece mesma sintaxe descrita acima.
Da mesma forma possvel alterar apenas outros parmetros:

spin_button.set_adjustment (adjustment)
spin_button.set_digits (digits)
spin_button.set_value (value)
Ou obter o valor do spin button:

float_value = spin_button.get_value()
int_value = spin_button.get_value_as_int()
A alterao do valor tambm pode ser feita de forma relativa atravs da funo spin:

spin_button.spin (direction, increment)


onde direction pode assumir um dos seguintes valores:
SPIN_STEP_FORWARD - Aumenta o valor do spin button de acordo com o valor increment
ou page_increment (do Adjustment) caso increment seja igual a 0;

54

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

SPIN_STEP_BACKWARD - Diminui o valor do spin button de acordo com o valor increment


ou page_increment (do Adjustment) caso increment seja igual a 0;
SPIN_PAGE_FORWARD - Aumenta o valor do spin button de acordo com o valor increment;
SPIN_PAGE_BACKWARD - Diminui o valor do spin button de acordo com o valor increment;
SPIN_HOME - Ajusta o valor para o mnimo do Adjustment;
SPIN_END - Ajusta o valor para o mximo do Adjustment;
SPIN_USER_DEFINED - Altera o valor pela quantidade especificada.
Algumas funes podem controlar a aparncia e o comportamento do boto de forma mais
detalhada:

spin_button.set_numeric (numeric)
Se numeric for True, isto garantir que o usurio pode digitar apenas nmeros no spin button;
caso contrrio outros caracteres podero ser digitados.

spin_button.set_wrap (wrap)
J este comando faz com que, caso wrap seja True, o boto retorne ao valor mnimo quando o
usurio atingir o valor mximo e vice-versa.

spin_button.set_snap_to_ticks (snap_to_ticks)
Esta funo faz com que valores "quebrados"sejam arredondados para seus equivalentes mais
prximos explicitados pelo Adjustment.

spin_button.set_update_policy (policy)
Onde policy pode ser UPDATE_ALWAYS ou UPDATE_IF_VALID, onde o primeiro atualiza o valor
mesmo que este seja invlido (aps uma alterao), e o segundo ignora erros enquanto estiver
convertendo para valor numrico.

8.4 Dilogo de seleo de arquivo


Este um dos widgets mais visto nos programas, por isso seria extremamente entediante
se cada desenvolvedor tivesse de programar tal funcionalidade, sem contar que provavelmente
seriam inconsistentes.
55

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Com isso em mente, os desenvolvedores do GTK+ incluiram isso como uma widget fcil de
se usar. Para cri-la:

filesel = gtk.FileSelection(title=None)
Para alterar o endereo sendo exibido, temos:

filesel.set_filename (filename)
O que ir atualizar a janela de maneira correspondente.
Para obter o arquivo selecionado:

filename = filesel.get_filename()
Como so vrias as widgets que compem o file selection dialog, possvel manipular essas
widgets "internas"normalmente. Elas seguem o seguinte padro de nomes:

56

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

filesel.dir_list
filesel.file_list
filesel.selection_entry
filesel.selection_text
filesel.main_vbox
filesel.ok_button
filesel.cancel_button
filesel.help_button
filesel.history_pulldown
filesel.history_menu
filesel.fileop_dialog
filesel.fileop_entry
filesel.fileop_file
filesel.fileop_c_dir
filesel.fileop_del_file
filesel.fileop_ren_file
filesel.button_area
filesel.action_area
Em particular, til manipular os sinais do ok_button, cancel_button e help_button para atribuir
funcionalides aos mesmos.
Ficar como exerccio ao leitor experimentar com os widgets apresentados nesta lio, j que
o funcionamento destes praticamente idntico aos apresentados anteriormente.

57

Captulo 9

Lio 7 - Controle avanado de layout


9.1 Alignment
O widget de alinhamento (Alignment) permite que se adicione um widget em uma posio e
tamanho relativo ao widget de alinhamento. Por exemplo, pode ser usado para se centralizar um
boto na tela.
Existem apenas dois comandos a serem aprendidos:

alignment = gtk.Alignment (xalign=0.0, yalign=0.0, xscale=0.0, yscale=0.0)


align.set (xalign, yalign, xscale, yscale)
Como de se esperar, o gtk.Alignment cria uma widget de alinhamento com os parmetros
especificados. Os valores so em ponto-flutuante, e devem variar entre 0.0 e 1.0. O xalign e
yalign ajustam a posio do widget no Alignment. Estas propriedades especificam a frao de
espao vazio que deve ser adicionado ao topo (yalign) ou esquerda (xalign) do widget inserido.
Os outros dois parmetros (xscale e yscale) definem a quantidade de espao vazio que deve
ser absorvido pela widget: 0.0 no absorve nenhum espao, e 1.0 absorve todo o espao vazio
disponvel. Naturalmente se ambos xscale e yscale forem iguais a 1.0, ento o uso do widget de
alinhamento perde seu sentido, j que todo espao vazio ser absorvido.
Para adicionar um (e apenas um) widget ao alinhamento, usa-se alignment.add(widget).
Screenshot para transmitir a idia:

58

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

9.2 Continer Fixed


O continer fixo permite que se posicione widgets em uma posio, ..., fixa. Esta posio
relativa ponta superior esquerda. Alm disso, a posio dos widgets pode ser alterada dinamicamente.
Novamente so poucos os comandos que precisam ser aprendidos:

fixed = gtk.Fixed()
fixed.put (widget, x, y)
fixed.move (widget, x, y)
O primeiro comando cria o widget (fixed) ao qual podero ser adicionados outros (widget). O
segundo adiciona a widget desejada (widget) ao widget fixo (fixed) na posio x e y. O terceiro
meramente muda a widget de posio.
possvel adicionar vrios widgets a um layout do tipo fixo.
Veja o seguinte exemplo:

59

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Estes devem ser usados com cautela, j que algumas configuraes locais (como tamanho
de fontes) sero ignorados, como a posio absoluta.

9.3 Continer layout


O continer Layout bastante similar ao ltimo visto (Fixed), com a exceo de que ele implementa uma rea infinita (ou melhor dizendo, at 2^32 pixels, devido a uma restrio do X).
Tambm se assemelha a um layout Fixed adicionado a uma ScrolledWindow, mas sem as barras
de rolagem. basicamente a mesma idia implementada de forma um pouco diferente.
A criao feita usando

layout = gtk.Layout (hadjustment=None, vadjustment=None)


Como se pode perceber, possvel especificar objetos do tipo Adjustment que o widget Layout
ir usar para barra de rolagem. Omiti-los significa que novos adjustments sero criados.
Para respectivamente adicionar e mover widgets, usa-se

layout.put(widget, x, y)
layout.put(widget, x, y)
O tamanho do continer Layout pode ser ajustado e obtido usando estes 2 comandos:

60

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

layout.set_size (width, height)


size = layout.get_size()
Finalmente, para obter e manipular os Adjustments

hadj = layout.get_hadjustment()
vadj = layout.get_vadjustment()
layout.set_hadjustment(adjustment)
layout.set_vadjustment(adjustment)
Perceba que este continer no inclui a barra de rolagem, sendo necessrio adicion-las manualmente.
Veja o seguinte exemplo:

9.4 Frames
Frames normalmente so usados para agrupar widgets de forma clara e objetiva. Ao contrrio
dos ltimos widgets de agrupamento, este agrupa de forma visvel ao usurio. Pode ser usado,
por exemplo, para separar sees em um grande formulrio, ou para separar opes de partes
distintas de um programa.
Cri-los simples:

frame = gtk.Frame (label=None)


O label a descrio (visvel) do agrupamento, que por padro estar no canto superior esquerdo.
Pode tambm ser omitido. possvel tambm alter-lo, atravs do comando

frame.set_label(label)

61

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Para mudar a posio do label, usa-se a funo

frame.set_label_align (xalign, yalign)


Onde o parmetro xalign pode variar entre 0.0 (esquerda) e 1.0 (direita). Atualmente o yalign no
usado.
A adio de uma widget ao frame feita usando-se frame.add (widget).
Exemplo:

9.5 Paned Window


Muitas vezes, por exemplo em um programa de e-mail, se deseja dividir uma rea em 2 partes
tal que o usurio possa controlar o tamanho de cada uma dessas reas. O GTK+ permite que se
faa isso diretamente atravs de 2 funes:

hpane = gtk.HPaned()
vpane = gtk.VPaned()
A HPane() criar uma divisria horizontal (ou seja, uma rea superior e outra inferior), o VPane()
far o seu equivalente vertical.
Para adicionar um elemento a cada uma das reas, temos os seguintes comandos:

paned.add1(child)
paned.add2(child)
O add1 adicionar o widget desejado ao painel superior (ou esquerdo), enquanto o add2 o
adicionar ao painel inferior (ou direito).

62

CDTC

Centro de Difuso de Tecnologia e Conhecimento

63

Brasil/DF

Captulo 10

Lio 8 - Progredindo com PyGTK


10.1 Progredindo com PyGTK
O que foi visto neste curso serve apenas de base para que o programador possa se aventurar
nas aplicaes mais avanadas do Python/GTK+. Com algumas centenas de funes, boa parte
do contedo no foi visto porque o curso se tornaria repetitivo, mas a base para seu entendimento
pleno est presente no curso.
Algumas fontes recomendadas para o contnuo aprendizado:
http://www.pygtk.org/
http://www.pygtk.org/tutorial.html
http://www.pygtk.org/reference.html
Com isto encerra-se a matria do curso propriamente dito.
Vale frisar que o curso foi bastante terico, e permite ao programador entender todos os conceitos e conhecer boa parte dos widgets e seu funcionamento. No entanto existem mtodos mais
fceis de se realizar a tarefa de diagramao de interfaces usando-se ferramentas tais como
Glade. Por no ser matria do curso em si, veremos isso apenas de forma superficial.

10.2 Matria extra: Criando interfaces grficas usando PyGTK e


Glade
O primeiro passo a instalao. No Debian e derivados, os pacotes necessrios so pythonglade2 (contm as bibliotecas para o Python) e glade-2 (contm o construtor de interfaces). Portanto como usurio root execute o seguinte comando:

apt-get install python-glade2 glade-2


Em seguida execute o glade-2, para se deparar com o seguinte:

64

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Inicialmente o Glade abre com um projeto novo e vazio. Repare que o projeto no contm
janelas ainda. Clique no cone da janela na paleta (o primeiro cone) que isto automaticamente
cria uma janela vazia. Em seguida, possvel alterar as propriedades do elemento recm-criado,
no caso a janela. Em "Propriedades"altere Name para JanelaPrincipal e Title para o que quiser.
Para adicionar elementos na janela, eles so "empacotados". Tendo a noo de como funciona no nvel do cdigo fonte (ou seja, tendo feito o curso) o programador j tem todo o conhecimento que precisa para criar interfaces com facilidade.
Vamos criar uma interface muito simples, com apenas 2 widgets: um label e um boto. Portanto siga os seguintes passos:
65

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

1. Clique no boto VBox (Vertical Box) na palheta;


2. Em seguida clique na janela para criar o VBox. Ir parecer uma janela solicitando o nmero
de clulas; reduza o valor para 2;
3. Clique no boto Label na palheta;
4. Clique na primeira clula do VBox recm-criado para adicion-lo l.
Viu? Temos um VBox com um elemento empacotado. Podemos alterar o contedo deste
rtulo para algo mais apropriado. Como a janela Properties sempre exibe as propriedades da
widget selecionada, mude o campo Label para "Clique abaixo!"Da mesma forma possvel alterar
muitas outras caractersticas que foram vistas ao longo do curso. Lembre-se de experimentar os
ajustes disponveis tambm nas outras abas, tais como Packing.
Falta agora somente o boto; clique no seu respectivo boto na palheta e clique na segunda
clula do VBox para adicion-lo. Em seguida altere o seu nome (Name) para botao1 e o rtulo
(Label) para "Clique em mim."
Ao trmino deste processo devemos ter algo assim:

66

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Clique em Project > Save para salvar o projeto em uma pasta prpria. O resultado disso
sero 2 arquivos XML que descrevem a interface. Abra-os em um editor de texto para ter uma
noo de como a interface descrita.
Ou seja, o Glade no gera cdigo em si, e sim uma descrio. O python-glade2 foi instalado
por esse motivo: permitir com que o cdigo faa uso de arquivos .glade.
OK, para ver a interface em funcionamento, crie um arquivo com o seguinte contedo:

import sys
import pygtk
67

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

import gtk
import gtk.glade
class GladeTest:
def __init__ (self):
self.wTree = gtk.glade.XML("project2.glade")
self.window = self.wTree.get_widget("window1")
gtk.main()
if __name__ == "__main__":
glade_test = GladeTest()
Execute-o e verifique seu funcionamento.
Perceba que a biblioteca gtk.glade est sendo usada; esta foi instalada no incio da lio. A
primeira chamada dentro do __init__ carrega a interface contida no arquivo XML (vide documentao aqui):
Este objeto respresenta uma instanciao da interface descrita em XML. Quando um desses
objetos criado, o arquivo XML lido, e a interface criada. O objeto gtk.glade.XML prov uma
interface para acessar as widgets atravs dos nomes associados a estas na descrio XML.
A segunda carrega o widget especificado que, no caso, uma janela. Finalmente gtk.main()
inicia a execuo.
Mas e se quisssemos usar sinais e eventos assim como fizemos at o momento? Vamos l...
O primeiro passo conectar o evento "destroy"da janela funo gtk.main_quit() como fizemos em todos os programas at o momento. Volte ao Glade e selecione a janela principal no
projeto. V para a janela de propriedades e escolha a aba Signals. Em "Signal"escolha "destroy"(disponvel em GtkObject).

68

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

E clique em "Add"para adicion-lo:

Com isso criamos um handler que funciona de forma semelhante a um sinal.


Faremos o mesmo para o boto; clique no boto "Clique em mim", e na janela Propriedades
(aba Signals) escolha o sinal "clicked". Em seguida clique em add.

69

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

Logo temos 2 handlers a gerenciar: on_window1_destroy e on_botao1_clicked. Esses nomes


podem ser alterados, mas recomendvel que sigam um padro.
Como, agora, fazer uso desses handlers? A biblioteca do glade para Python permite que isso
seja de forma fcil, atribuindo vrios handlers a funes diferentes. Veja o cdigo abaixo:

import
import
import
import

sys
pygtk
gtk
gtk.glade

class GladeTest:
def botao_clicked (self, widget):
print "botao clicado"
def __init__ (self):
self.wTree = gtk.glade.XML("project2.glade")
self.window = self.wTree.get_widget("window1")
dic = { "on_window1_destroy" : gtk.main_quit,
"on_botao1_clicked" : self.botao_clicked }
self.wTree.signal_autoconnect (dic)
gtk.main()
if __name__ == "__main__":
70

CDTC

Centro de Difuso de Tecnologia e Conhecimento

Brasil/DF

glade_test = GladeTest()
Salve este cdigo em um arquivo na mesma pasta do projeto Glade e execute-o. O resultado
simples:

E como j deve ter sido possvel perceber, o dicionrio dic associa cada handler a uma funo.
A funo signal_autoconnect faz a associao automaticamente e de uma s vez.

10.3 Despedidas
Infelizmente o curso no ir se aprofundar mais do que isso em Glade, ficando isso a cargo
do leitor. Informaes sobre Glade podem ser encontradas na Web; a pgina do prprio Glade
um bom ponto de partida: http://glade.gnome.org/.
E com isso conclumos o curso. Boa parte da matria foi vista, mas recomenda-se ao aluno
que nunca pare de aprender novas tecnologias e aprofundar-se nas existentes; busque cursos,
sites, leia, mas no fique parado!
Espero que tenham gostado!

71