SlideShare uma empresa Scribd logo
1 de 72
Baixar para ler offline
Python-GTK
23 de maio de 2007
Sumário
I Sobre essa Apostila 3
II Informações Básicas 5
III Python-GTK 10
1 O que é o Curso 11
2 Plano de ensino 12
2.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2 Público Alvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Pré-requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.4 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6 Cronograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.7 Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.8 Avaliação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.9 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3 Lição 1 - Apresentando PyGTK 15
3.1 Um breve histórico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Primeiros passos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3 Conferindo a instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4 Lição 2 - Apresentando Widgets, Signals e Callbacks 19
4.1 Conceitos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2 Um exemplo prático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5 Lição 3 - Widgets elementares 24
5.1 Empacotando widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5.2 O widget do botão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
6 Lição 4 - Widgets miscelâneas 1 34
6.1 Adjustments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
6.2 Widgets de faixa de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.3 Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.4 Áreas com barras de rolagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.5 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
7 Lição 5 - Widgets miscelâneas 2 43
7.1 Barras de progresso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
7.2 Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
7.3 Barras de status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.4 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
8 Lição 6 - Widgets miscelâneas 3 51
8.1 Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
8.2 Entrada de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
8.3 Spin buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
8.4 Diálogo de seleção de arquivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9 Lição 7 - Controle avançado de layout 58
9.1 Alignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
9.2 Contêiner Fixed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
9.3 Contêiner layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
9.4 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9.5 Paned Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10 Lição 8 - Progredindo com PyGTK 64
10.1 Progredindo com PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
10.2 Matéria extra: Criando interfaces gráficas usando PyGTK e Glade . . . . . . . . . . 64
10.3 Despedidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
2
Parte I
Sobre essa Apostila
3
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Conteúdo
O conteúdo dessa apostila é fruto da compilação de diversos materiais livres publicados na in-
ternet, disponíveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br.
O formato original deste material bem como sua atualização está disponível dentro da licença
GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seção de
mesmo nome, tendo inclusive uma versão traduzida (não oficial).
A revisão e alteração vem sendo realizada pelo CDTC (suporte@cdtc.org.br) desde outubro
de 2006. Críticas e sugestões construtivas são bem-vindas a qualquer tempo.
Autores
A autoria deste é de responsabilidade de Pedro Guerra Brandão.
O texto original faz parte do projeto Centro de Difusão de Tecnologia e Conhecimento, que
vem sendo realizado pelo ITI (Instituto Nacional de Tecnologia da Informação) 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 país.
Informações adicionais podem ser obtidas através do email ouvidoria@cdtc.org.br, ou da
home page da entidade, através da URL http://www.cdtc.org.br.
Garantias
O material contido nesta apostila é isento de garantias e o seu uso é de inteira responsabi-
lidade do usuário/leitor. Os autores, bem como o ITI e seus parceiros, não se responsabilizam
direta ou indiretamente por qualquer prejuízo oriundo da utilização do material aqui contido.
Licença
Copyright ©2006, Instituto Nacional de Tecnologia da Informação (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 APOS-
TILA. A copy of the license is included in the section entitled GNU Free Documentation
License.
4
Parte II
Informações Básicas
5
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Sobre o CDTC
Objetivo Geral
O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a dissemina-
ção de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do
desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira.
Objetivo Específico
Auxiliar o Governo Federal na implantação do plano nacional de software não-proprietário e
de código fonte aberto, identificando e mobilizando grupos de formadores de opinião dentre os
servidores públicos e agentes políticos da União Federal, estimulando e incentivando o mercado
nacional a adotar novos modelos de negócio da tecnologia da informação e de novos negócios
de comunicação com base em software não-proprietário e de código fonte aberto, oferecendo
treinamento específico para técnicos, profissionais de suporte e funcionários públicos usuários,
criando grupos de funcionários públicos que irão treinar outros funcionários públicos e atuar como
incentivadores e defensores de produtos de software não proprietários e código fonte aberto, ofe-
recendo conteúdo técnico on-line para serviços de suporte, ferramentas para desenvolvimento de
produtos de software não proprietários e de seu código fonte livre, articulando redes de terceiros
(dentro e fora do governo) fornecedoras de educação, pesquisa, desenvolvimento e teste de pro-
dutos de software livre.
Guia do aluno
Neste guia, você terá reunidas uma série de informações importantes para que você comece
seu curso. São elas:
• Licenças para cópia de material disponível
• Os 10 mandamentos do aluno de Educação a Distância
• Como participar dos foruns e da wikipédia
• Primeiros passos
É muito importante que você entre em contato com TODAS estas informações, seguindo o
roteiro acima.
Licença
Copyright ©2006, Instituto Nacional de Tecnologia da Informação (cdtc@iti.gov.br).
6
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos
da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior
públicada pela Free Software Foundation; com o Capitulo Invariante SOBRE ESSA
APOSTILA. Uma cópia da licença está inclusa na seção entitulada "Licença de Docu-
mentação Livre GNU".
Os 10 mandamentos do aluno de educação online
• 1. Acesso à Internet: ter endereço eletrônico, um provedor e um equipamento adequado é
pré-requisito para a participação nos cursos a distância.
• 2. Habilidade e disposição para operar programas: ter conhecimentos básicos de Informá-
tica é necessário para poder executar as tarefas.
• 3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distân-
cia conta muitos pontos, pois irá colaborar para o processo ensino-aprendizagem pessoal,
dos colegas e dos professores.
• 4. Comportamentos compatíveis com a etiqueta: mostrar-se interessado em conhecer seus
colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo.
• 5. Organização pessoal: planejar e organizar tudo é fundamental para facilitar a sua revisão
e a sua recuperação de materiais.
• 6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigações e
realizá-las em tempo real.
• 7. Curiosidade e abertura para inovações: aceitar novas idéias e inovar sempre.
• 8. Flexibilidade e adaptação: requisitos necessário à mudança tecnológica, aprendizagens
e descobertas.
• 9. Objetividade em sua comunicação: comunicar-se de forma clara, breve e transparente é
ponto - chave na comunicação pela Internet.
• 10. Responsabilidade: ser responsável por seu próprio aprendizado. O ambiente virtual não
controla a sua dedicação, mas reflete os resultados do seu esforço e da sua colaboração.
Como participar dos fóruns e Wikipédia
Você tem um problema e precisa de ajuda?
Podemos te ajudar de 2 formas:
A primeira é o uso dos fóruns de notícias e de dúvidas gerais que se distinguem pelo uso:
. O fórum de notícias tem por objetivo disponibilizar um meio de acesso rápido a informações
que sejam pertinentes ao curso (avisos, notícias). As mensagens postadas nele são enviadas a
7
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
todos participantes. Assim, se o monitor ou algum outro participante tiver uma informação que
interesse ao grupo, favor postá-la aqui.
Porém, se o que você deseja é resolver alguma dúvida ou discutir algum tópico específico do
curso. É recomendado que você faça uso do Forum de dúvidas gerais que lhe dá recursos mais
efetivos para esta prática.
. O fórum de dúvidas gerais tem por objetivo disponibilizar um meio fácil, rápido e interativo
para solucionar suas dúvidas e trocar experiências. As mensagens postadas nele são enviadas
a todos participantes do curso. Assim, fica muito mais fácil obter respostas, já que todos podem
ajudar.
Se você receber uma mensagem com algum tópico que saiba responder, não se preocupe com a
formalização ou a gramática. Responda! E não se esqueça de que antes de abrir um novo tópico
é recomendável ver se a sua pergunta já foi feita por outro participante.
A segunda forma se dá pelas Wikis:
. Uma wiki é uma página web que pode ser editada colaborativamente, ou seja, qualquer par-
ticipante pode inserir, editar, apagar textos. As versões antigas vão 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 "Wikipé-
dia", uma experiência grandiosa de construção de uma enciclopédia de forma colaborativa, por
pessoas de todas as partes do mundo. Acesse-a em português pelos links:
• Página principal da Wiki - http://pt.wikipedia.org/wiki/
Agradecemos antecipadamente a sua colaboração com a aprendizagem do grupo!
Primeiros Passos
Para uma melhor aprendizagem é recomendável que você siga os seguintes passos:
• Ler o Plano de Ensino e entender a que seu curso se dispõe a ensinar;
• Ler a Ambientação do Moodle para aprender a navegar neste ambiente e se utilizar das
ferramentas básicas do mesmo;
• Entrar nas lições seguindo a seqüência descrita no Plano de Ensino;
• Qualquer dúvida, reporte ao Fórum de Dúvidas Gerais.
Perfil do Tutor
Segue-se uma descrição do tutor ideal, baseada no feedback de alunos e de tutores.
O tutor ideal é um modelo de excelência: é consistente, justo e profissional nos respectivos
valores e atitudes, incentiva mas é honesto, imparcial, amável, positivo, respeitador, aceita as
idéias dos estudantes, é paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar.
8
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
A classificação por um tutor desta natureza proporciona o melhor feedback possível, é crucial, e,
para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem.’ Este tutor
ou instrutor:
• fornece explicações claras acerca do que ele espera, e do estilo de classificação que irá
utilizar;
• gosta que lhe façam perguntas adicionais;
• identifica as nossas falhas, mas corrige-as amavelmente’, diz um estudante, ’e explica por-
que motivo a classificação foi ou não foi atribuída’;
• tece comentários completos e construtivos, mas de forma agradável (em contraste com um
reparo de um estudante: ’os comentários deixam-nos com uma sensação de crítica, de
ameaça e de nervossismo’)
• dá uma ajuda complementar para encorajar um estudante em dificuldade;
• esclarece pontos que não foram entendidos, ou corretamente aprendidos anteriormente;
• ajuda o estudante a alcançar os seus objetivos;
• é flexível quando necessário;
• mostra um interesse genuíno em motivar os alunos (mesmo os principiantes e, por isso,
talvez numa fase menos interessante para o tutor);
• escreve todas as correções de forma legível e com um nível de pormenorização adequado;
• acima de tudo, devolve os trabalhos rapidamente;
9
Parte III
Python-GTK
10
Capítulo 1
O que é o Curso
Python é uma linguagem interpretada, orientada a objetos, extensível e de fácil utilização.
GTK+ (Gimp Tool Kit) é uma biblioteca para criar interfaces gráficas.
Para utilizá-las em conjunto, foi criado o PyGTK, que consiste em uma série de módulos para
prover uma interface ao Python para acesso ao GTK, possibilitando ao desenvolvedor a criação
de sistemas com interfaces gráficas riquíssimas.
11
Capítulo 2
Plano de ensino
2.1 Objetivo
Habilitar técnicos e programadores a usarem a biblioteca PyGTK, para Python.
2.2 Público Alvo
Técnicos e Programadores que desejem trabalhar com PyGTK.
2.3 Pré-requisitos
Os usuários deverão ser, necessariamente, indicados por empresas públicas e ter certo co-
nhecimento da linguagem Python. É recomendável um conhecimento mínimo nos recursos es-
pecíficos da linguagem (por exemplo dicionários e tuplas). Noções de orientação a objetos em
Python também são recomendáveis.
Não é necessário conhecimento prévio de GTK+.
2.4 Descrição
O curso de Introdução ao Python será realizado na modalidade EAD e utilizará a plataforma
Moodle como ferramenta de aprendizagem. Ele é composto de um módulo de aprendizado que
será dado na primeira semana e um módulo de avaliação que será dado na segunda semana. O
material didático estará disponível on-line de acordo com as datas pré-estabelecidas no calendá-
rio. A versão utilizada para o PyGTK será a 2.10.
2.5 Metodologia
O curso está dividido da seguinte maneira:
12
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
2.6 Cronograma
• 1ª Semana - Introdução + Conceitos básicos;
• 2ª Semana - Conceitos avançados.
Todo o material está no formato de livro, e estará disponível ao longo do curso. O livro poderá
ser acessado quantas vezes forem necessárias. Aconselhamos a leitura de "Ambientação do
Moodle", para que você conheça o produto de Ensino a Distância, evitando dificuldades advindas
do "desconhecimento"sobre o mesmo.
Ao final de cada semana do curso será disponibilizada a prova referente ao módulo estudado
anteriormente que também conterá perguntas sobre os textos indicados. Utilize o material de
cada semana e os exemplos disponibilizados para se preparar para prova.
Os instrutores estarão à sua disposição ao longo de todo curso. Qualquer dúvida deve ser
disponibilizada no fórum ou enviada por e-mail. Diariamente os monitores darão respostas e es-
clarecimentos.
2.7 Programa
O curso oferecerá o seguinte conteúdo:
Semana 1:
• Visão Geral e Histórico;
• Introdução;
• Um breve exemplo;
• Modificando parâmetros;
• Callbacks;
• Widgets básicos.
Semana 2:
1. Outras widgets;
2. Aperfeiçoando o controle de layout;
3. Automatizando o processo de criação de interfaces.
2.8 Avaliação
Toda a avaliação será feita on-line.
Aspectos a serem considerados na avaliação:
• Iniciativa e autonomia no processo de aprendizagem e de produção de conhecimento;
• Capacidade de pesquisa e abordagem criativa na solução dos problemas apresentados.
13
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Instrumentos de avaliação:
• Participação ativa nas atividades programadas;
• Avaliação ao final do curso;
• O participante fará várias avaliações referente ao conteúdo do curso. Para a aprovação e
obtenção do certificado o participante deverá obter nota final maior ou igual a 6.0 de acordo
com a fórmula abaixo:
• Nota Final = ((ML x 7) + (AF x 3)) / 10 = Média aritmética das lições;
• AF = Avaliações.
2.9 Bibliografia
• Site official: http://www.python.org
• Guia: http://www.pygtk.org/pygtk2tutorial/index.html
14
Capítulo 3
Lição 1 - Apresentando PyGTK
3.1 Um breve histórico
Embora o curso assuma um certo conhecimento de Python, não é necessário que o aluno
tenha experiência com GTK+. Entretanto, isto não nos impede de oferecer uma visão geral de
todos os componentes envolvidos.
GTK+
O GIMP Toolkit, popularmente conhecido por GTK+, é um dos mais famosos toolkits voltados
para a criação de interfaces gráficas (referidas GUIs daqui em diante). O que, então, 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 além.
O GTK+ é um dos pilares do famoso ambiente de janelas GNOME, portanto aplicações base-
adas nesta biblioteca podem ser facilmente identificadas pelo visual em comum.
Seus autores incluem Spencer Kimball, Peter Mattis e Josh MacDonald, todos os quais traba-
lhavam na Universidade de Berkeley à época de criação do GTK+/GIMP.
15
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Os menus, botões, formulários, dropdowns e outros elementos da janela (widgets) possuem
um visual bastante padronizado, mesmo entre os vários temas disponíveis no GTK+ (acima re-
presentado está o tema padrão da distribuição Ubuntu).
Python
Python é uma linguagem de programação de alto nível orientada a objetos. Seu criador, Guido
van Rossum, a criou em 1991 com o objetivo de enfatizar o esforço do programador sobre o es-
forço computacional, tornando-se uma linguagem de fácil aprendizagem.
Além do mais, Python se difere de outras linguagens no quesito simplicidade e legibilidade.
Por exemplo, a indentação do código é de prima importância para que o código execute correta-
mente, o que conseqüentemente facilita bastante a sua compreensão e padroniza os programas
com um look similar. O caractere ; não é necessário para indicar o término de um comando,
servindo a quebra de linha (n) para tal.
Quanto ao aspecto de simplicidade, isto apenas se aplica ao núcleo da linguagem. Há uma
vasta quantidade de bibliotecas disponíveis, inclusive distribuídas com o Python. Uma destas,
aliás, é o...
16
CDTC Centro de Difusão 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+
através da biblioteca PyGTK. Dispensando explicações sobre a origem de seu nome, partiremos
para um overview geral.
O PyGTK é um conjunto de wrappers (vulgarmente "envoltórios") para a biblioteca GTK+. As-
sim como o Python, o PyGTK é software livre, no entanto é distribuído sob a licença LGPL. É de
autoria de um dos desenvolvedores do GNOME, James Henstridge, e hoje possui uma equipe
maior, inclusive com grande participação da comunidade através de patches e bug reports.
Um dos méritos do PyGTK é ter sido escolhido como o ambiente de escolha para aplicações
rodando nos sistemas do projeto One Laptop Per Child. Além 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.
Instação
O Linux é, decididamente, a plataforma ideal para este tipo de desenvolvimento e é a que nós
recomendamos. Não obstante, usuários de Windows podem seguir com o curso, assim como
os de Mac OS X. Apenas a etapa de instalação deverá diferir do que está apresentado no curso
(Devido à indisponibilidade de recursos, a tarefa de instalçao será deixada por conta do usuário).
Linux
Talvez até excessivamente simples, para se instalar o PyGTK nas distribuições Debian e de-
rivados (tais como Ubuntu), basta instalar o pacote python-gtk2:
apt-get install python-gtk2
Isto irá instalar as bibliotecas necessárias. Caso seja solicitado para instalar pacotes depen-
dentes, aceite.
Caso esteja usando outra distribuição, procure um pacote com este nome ou pygtk.
17
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
3.3 Conferindo a instalação
OK, tecnicamente estamos prontos para seguir em frente e aprendermos os conceitos. Mas
primeiro vamos verificar se a etapa de instalação realmente foi concluída com êxito.
Crie um arquivo com o seguinte código 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 dúvida ao fórum! Não será possível prosseguir com o
curso se este exemplo não funcionar.
Não se preocupe com o código, iremos detalhá-lo mais adiante.
Perceba que este exemplo apenas exibe uma janela vazia. Nem mesmo o botão de fechá-la
funciona. Veremos os motivos mais adiante.
18
Capítulo 4
Lição 2 - Apresentando Widgets,
Signals e Callbacks
4.1 Conceitos básicos
Antes de prosseguirmos com os exemplos, iremos dar uma breve olhada nos conceitos que
serão explorados. Estes são de crucial importância para o entendimento pleno da matéria. Usuá-
rios que não possuem experiência prévia com GTK+: leiam esta página atenciosamente.
Widgets
Um conceito extremamente simples; derivado de window gadets (apetrechos de janela), o
termo pode representar qualquer elemento de uma janela, tais como botões, barras de rolagem,
menus dropdown, campo de texto, barra de título, barra de ferramentas e qualquer outra parafer-
nália 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 função
correspondente. Este conceito é denominado sinal (entretanto este conceito é meramente seme-
lhante aos signals Unix, a implementação é bastante diferente). Quando ocorre um evento, como
o apertar de um botão, o widget irá emitir um sinal. Os sinais variam de widget para widget. Por
exemplo, o botão herda sinais de várias classes:
• gobject.GObject: "activate", "clicked", "enter", "leave", "pressed"e "released";
• gtk.Object: "destroy";
• gtk.Widget: "accel-closures-changed", "button-press-event", "button-release-event", "can-
activate-accel", "child-notify", dentre muitas, muitas outras;
19
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
• gtk.Container: "add", "check-resize", "remove", "set-focus-child".
Para o exemplo do botão, 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 possível de sinais é imensa para um dado widget, e neste curso
iremos ver apenas os signals mais freqüentemente utilizados.
Callback
Quando um sinal ocorre, uma função callback pode ser acionada. Esta função 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, então, associar uma função callback a um
signal? Para tal, os objetos em GTK possuem a função connect:
handler_id = object.connect (name, func, func_data)
Nesta linha, object é a instância do GtkWidget que estará emitindo o sinal, e o primeiro argu-
mento (name) indica o nome do sinal que irá acionar o callback (por exemplo "clicked"ou "des-
troy"). O segundo argumento (func) indica a função (callback) que deverá ser acionada. Repare
que o argumento é o *objeto* da função, e não o seu nome. No terceiro argumento, estão os
dados que serão repassados para a função.
Portanto o callback deverá ter o seguinte cabeçalho:
def callback_func (widget, callback_data)
O primeiro parâmetro será um ponteiro para a widget que emitiu o sinal, e o segundo parâme-
tro um ponteiro para os dados definidos na chamada do connect.
Naturalmente, se a função callback for definida em um método, sua forma geral será:
def callback_func_method (self, widget, callback_data)
Onde self representa a instância do object acionando o método.
(Existem exceções quanto aos seus argumentos, mas de forma geral serão estes.)
Juntos, estes dois conceitos (signals e callbacks) formam boa parte dos fundamentos por trás
do GTK+.
Eventos
Além dos sinais, existem também eventos, que refletem o mecanismo de eventos do X. São
muito similares a sinais, no sentido que callbacks também podem ser associados a estes. Re-
fletem eventos tais como o requisitado fechamento de um programa, ou o clique do mouse (ou
duplo-, triplo-clique). No entanto, o cabeçalho de suas funções callback é um pouco diferente:
def callback_func (widget, event, callback_data)
ou, no caso de uma função callback definida em um método:
def callback_func_method (self, widget, event, callback_data)
20
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Como fazer para conectar uma função callback a um evento? Usando connect:
handler_id = object.connect (name, func)
Por exemplo, para um botão 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 função:
button_click_event (widget, event, callback_data)
O valor que esta função 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
não deverá propagar (isto é, se houver mais de um callback associado a um evento). Se retornar
False, então o evento será propagado.
Se isto ainda está um pouco nebuloso, não se preocupe. Exemplos tornarão os conceitos
bem mais claros.
Desconectando callbacks
É claro, também é possível desassociar um callback de um sinal ou um evento. O comando a
ser usado é o seguinte:
object.disconnect (handler_id)
4.2 Um exemplo prático
Agora que temos um embasamento teórico podemos partir para exemplos.
Crie um arquivo com o nome botao1.py com o seguinte conteúdo:
#!/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 através da geração de uma instância da classe
Window. """
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
""" Ajustamos alguns parâmetros referentes à janela:
- Ajusta o espaçamento da borda para 10 (espaço entre
borda e os widgets)
- Seta o título da janela
21
CDTC Centro de Difusão 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 não fosse feito, o programa
continuaria sua execução mesmo após o fechamento da
janela """
self.janela.connect ("delete_event", self.delete_event)
""" Em seguida cria-se um botão (perceba que é a isntância de
uma classe. """
self.botao = gtk.Button ("Hey there")
""" IMPORTANTÍSSIMO: (quase) todo elemento deve ser
explicitamente exibido para que apareça na tela. """
self.botao.show ()
""" Adiciona o botão à janela. Para adicionar mais elementos
será necessário 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 código é bastante intuitiva; a criação da janela, atribuição de parãmetros, cria-
ção do botão. Há dois elementos importantes neste exemplo: o callback e as chamadas a show().
22
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
O método show() causa uma widget a ser exibida assim que possível. Antes de se chamar
este método a widget não será mostrada! Naturalmente, para que uma widget seja visualizada, é
necessário também que todos os contêineres da widget também sejam explicitamente mostrados.
Quando um contêiner "toplevel"(que contém 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 começar das widgets internas até
chegar nas widgets externas; caso contrário o usuário irá ver a atualização dos componentes
dependendo da complexidade gráfica 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 solicitação de fe-
chamento do programa. Isto pode ocorrer quando o usuário clica no X para fechar, ou pelo
gerenciador de tarefas. Em todo caso, se não tratarmos este evento a widget em questão (no
caso a janela em si) será finalizada, no entanto o gtk.main() continuará sua execução (Tente isto:
remova o self.janela.connect e veja o que ocorre depois de fechada a janela). Por esse motivo é
necessário explicitamente executar gtk.main_quit(). O dado passado pelo delete_event (no quarto
parâmetro da função callback) é None e portanto é ignorado pela função callback.
Você consegue ver a utilidade disto? Nem sempre que o usuário fecha uma janela ele neces-
sariamente teve tal intenção. 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 responsável por essas ações.
23
Capítulo 5
Lição 3 - Widgets elementares
5.1 Empacotando widgets
Até o momento trabalhamos com apenas uma widget na janela principal. Como fazer para
agrupá-las?
Há várias formas de fazê-lo; a mais comum delas são caixas (boxes).
Boxes
Boxes são contêineres 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, depen-
dendo da forma como sejam criados. É comum usar uma combinação de boxes (boxes dentro de
boxes) para criar o efeito desejado.
Como é de se esperar, para criar um HBox basta gerar uma instância de gtk.HBox(). Para
adicionar elementos a um box, usa-se o método pack_start() e pack_end(), onde o primeiro in-
sere da esquerda para a direita e o último da direita para a esquerda. Boxes podem agrupar tanto
widgets quanto outros boxes.
Vale frisar que botões são contêineres por si só, mas normalmente usa-se apenas um label
dentro do botão.
Como criá-los?
O cabeçalho da HBox() está definido da seguinte forma:
gtk.HBox (homogeneous = False, spacing = 0)
Se o primeiro parâmetro for True, isto garantirá que todos os elementos tenham exatamente a
mesma largura. O segundo parâmetro especifica o espaçamento entre os elementos.
Além disso, a forma como se agrupa os elementos também altera a aparência geral do layout:
box.pack_start(child, expand=True, fill=True, padding=0)
24
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Box é o container onde o widget será empacotado e o parâmetro child deve ser o objeto do widget
a ser empacotado. Os outros parâmetros controlam como os widgets inseridos se adaptarão ao
box (ou vice-versa):
• Expand define se o objeto se ajustará para ocupar todo o espaço disponível no widget (True)
ou se o box se reduzirá ao tamanho dos widgets (False). Se isto for False, é possível manter
todos os widgets alinhados no canto direito ou esquerdo do box;
• O parâmetro fill somente tem efeito se o expand for false; neste caso, ele controla se o es-
paço remanescente no box deverá ser alocado como espaçamento entre os widgets (False)
ou se os widgets receberão o espaço remanescente (True).
• Finalmente padding é o espaçamento que será adicionado a ambos os lados do widget.
Qual a diferença entre padding (fornecido no pack_start() ou pack_end()) e spacing (fornecido
no HBox() ou VBox())? O spacing é o espaço adicionado entre os elementos, e o padding é o
espaço adicionado a ambos os lados de um elemento.
Toda essa teoria também 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 parâmetros referentes à janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botões 2")
self.janela.resize (300, 50)
# Em seguida cria-se os botões:
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 Difusão 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 homogêneo (todos elementos ocupam o mesmo
# espaço) com espaçamento 10 entre os elementos.
self.hbox = gtk.HBox (True, 10)
# Empacota os botões no HBox
self.hbox.pack_start (self.botao1)
self.hbox.pack_start (self.botao2)
# Adiciona o botão à janela. Para adicionar mais elementos
# será necessário criar um contêiner, 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 além disso, encapsulando vários boxes e criando um layout extre-
mamente flexível.
26
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
5.2 O widget do botão
Vimos no exemplo anterior que botões podem ser customizados com parâmetros adicionais.
Já sabemos praticamente tudo sobre botões, mas há alguns truques dos quais devemos estar
cientes.
A sintaxe básica para criar um botão é:
button = gtk.Button(label=None, stock=None)
O primeiro parâmetro especifica o texto a ser exibido (opcional) e o stock pode ser uma de várias
constantes pré-definidas com padrões de botões (também opcional). O stock (STOCK_QUIT)
usado no exemplo da lição anterior é um botão tipicamente usado para sair de programas. A
variedade completa está disponível em http://www.pygtk.org/docs/pygtk/gtk-stock-items.html.
Dica: Sendo a usabilidade um aspecto muito importante nos aplicativos de atualmente, é co-
mum 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 botões
vistos nesta página. Assim, ao apertar Alt+(letra sublinhada), seria como se o usuário clicasse no
botão.
Customizando o visual
Há de se convir que as possibilidades são bastantes limitadas se não se pode ao menos criar
um botão com um ícone customizado; tem de haver uma forma de se criar um botão 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 parâmetros referentes à janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botões 3")
self.janela.resize (100, 50)
# Assegura-se que a janela será fechada corretamente.
# (Lembre-se de funções 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 Difusão de Tecnologia e Conhecimento Brasil/DF
# Em seguida cria-se o botão (perceba a ausência do label)
self.botao = gtk.Button ()
# Cria-se o box do botão...
self.box = self.xpm_label_box ("tartan.xpm", u"faça algo!")
# E adiciona o HBox com os conteúdos do botão
self.botao.add (self.box)
# Exibe-os
self.box.show()
self.botao.show ()
# Adiciona o botão á janela. Para adicionar mais elementos
# será necessário 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 não-homogêneo (o ícone é menor que o label)
# e sem espaçamento.
box = gtk.HBox (False, 0)
# Adiciona uma pequena borda como em um botão
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
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
def main (self):
gtk.main()
if __name__ == "__main__":
janela = Janela()
janela.main()
Preste atenção ao exemplo e perceberá que não é possível criar um botão com um pixmap
diferenciado "nativamente", na realidade criamos um HBox no qual estão contidos o pixmap e
o label. O método que usamos, xpm_label_box, poderia com facilidade ser usado em qualquer
outro elemento que possa ser um contêiner.
A propósito, para se criar o pixmap podemos usar uma diversidade de programas, inclusive o
open-source GIMP.
Outros botões
Outras formas de botões são freqüentemente vistas, como toggle buttons (que possuem um
relevo para indicar se estão selecionados ou não), checkboxes (uma pequena caixa que pode
ser marcada ou desmarcada) e radio buttons (conjunto de botões dos quais apenas um pode ser
selecionado através de pequenas bolas). Na ausência de uma tradução melhor irei me referir aos
nomes originais, em inglês.
Toggle buttons
Toggle buttons são derivados de botões normais e são muito similares, exceto o fato de que
sempre estarão em um de dois estados (pressionado ou não), alterados através de um clique.
Seu estado se altera a cada clique. Estes botões são a base para check buttons e radio buttons,
com muitas similaridades na implementação.
Como criar um?
botao = gtk.ToggleButton(label=None)
Cada widget deste tipo possui uma função get_active() que retorna se o botão está pressionado
ou não; o sinal que indica que o estado de um botão foi alterado é o "toggled"; juntando as
duas peças do quebra-cabeça, rapidamente descobrimos como trabalhar com as mudanças de
estados:
def toggle_button_callback (widget, data):
if (widget.get_active()):
# botão está pressionado
else:
# botão não está pressionado
29
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
A função get_active() pode ser usada sempre que se precisar obter o estado do botão, sendo
que esta retornará True (pressionado) ou False (não-pressionado).
E como alterar o estado do botão manualmente? Usa-se o seguinte método:
botao.set_active(active)
Onde active pode ser True (pressionado) ou False (não-pressionado). O valor inicial (quando o
botão é gerado) é False.
Perceba que quando esta função for chamada, os sinais "clicked"e "toggled"serão emitidos
pelo botão!
Check buttons
Como já foi mencionado, seu funcionamento é muito parecido com toggle buttons, e de fato,
são simplesmente toggle buttons com uma aparência diferente, já que os labels ficam na lateral
da "caixinha"que o usuário marca. A criação é feita da seguinte forma:
botao = gtk.CheckButton(label=None)
O callback de verificação 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 são similares aos check buttons, mas possuem a diferenciação de serem agru-
pados de tal forma que apenas um pode estar selecionado por vez. Isto é bom quando a lista de
opções é razoavelmente pequena.
A criação é feita com o seguinte comando:
botao = gtk.RadioButton (group=None, label=None)
Perceba a existência de um argumento extra. Radio buttons requerem de um grupo para funcio-
nar. 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 botão.
Para adicionar mais radio buttons para o grupo, passe a referência para um radio button nas
chamadas subseqüentes a gtk.RadioButton().
É também uma boa idéia explicitar qual botão deverá estar apertado inicialmente com o co-
mando
button.set_active(is_active)
Isto funciona da mesma forma como foi descrito acima. Uma vez que radio buttons estão agrupa-
dos, apenas um do grupo pode estar ativo. Por este motivo, se o usuário clicar em um, depois em
30
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
outro botão de dado grupo, o primeiro radio button irá emitir o sinal "toggled"(já que foi desativado)
e o segundo botão também irá emitir o sinal "toggled"(já que acabara de ser pressionado).
Recapitulando
No intuito de fixar e exemplificar o que foi visto acima, preste atenção no exemplo botao4.py.
#!/usr/bin/env python
# -*- coding: latin-1 -*-
import pygtk
import gtk
class Janela:
# Função callback que monitora o estado dos botões
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 parâmetros referentes à janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Botões + botões")
self.janela.resize (200, 400)
# Assegura-se que a janela será fechada corretamente.
# (Lembre-se de funções 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 Difusão de Tecnologia e Conhecimento Brasil/DF
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 conteúdos do botão
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 ação:
32
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Mensagens são emitidas no terminal a cada alteração nos botões.
Repare como a criação do radio button é diferente dos demais, assim como o seu funciona-
mento.
33
Capítulo 6
Lição 4 - Widgets miscelâneas 1
6.1 Adjustments
Um elemento muito frequente em interfaces com usuários é o "slider", uma barra de rolagem
através da qual o usuário 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 trás de seu funcionamento.
Adjustments
Uma aplicação necessita reagir às ações de usuários nestes widgets; isto poderia ser feito
através de um sinal emitido pela widget quando houvesse uma mudança no seu valor, no qual
a widget transmite também o novo valor para a função responsável. Mas e se quiséssemos as-
sociar os ajustes de várias widgets, de tal forma, que mudar o valor em uma widget alteraria
outra? Uma aplicação prática para isto seria conectar as barras de rolagem de tal forma a sele-
cionar o conteúdo a ser visualizado, por exemplo, de uma imagem(Será isso um presságio?). Se
cada widget de ajuste tivesse de emitir um sinal a cada mudança de valor, o programador teria
de escrever gerenciadores de sinais para transmitir a mudança de valor de uma widget para outra.
O GTK+ nos auxilia através do objeto Adjustment, que não é uma widget, mas uma forma
através da qual widgets podem transmitir informações sobre ajustes de uma forma abstrata e
flexível. Além de guardarem parâmetros de configuração e valores de widgets (ou várias delas),
Adjustments podem emitir sinais, assim como widgets convencionais, e isso pode ser usado para
propagar informações entre várias widgets separadas.
Você já conhece bem esse tipo de widget; são barras de progresso, janelas com barra de
rolagem, dentre outros.
Criando um Adjustment
A sintaxe é simples:
34
CDTC Centro de Difusão 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 parâmetro value indica o valor inicial a ser atribuído à widget. Lower e upper são o menor e
maior valores que podem ser assumidos pelo widget. Step_incr define o intervalo entre os ajus-
tes, page_incr define o maior intervalo entre estes. Finalmente o page_size é o parâmetro que
contém a área visível no caso de uma widget à qual se aplique.
Os widgets ajustáveis podem ser divididos naqueles que necessitam de uma unidade espe-
cífica (por exemplo pixels) e aqueles que usam números arbitrários. Alguns widgets que usam
números arbitrários incluem a barra de rolagem e a barra de progresso. Estas podem ser ajus-
tadas pelo mouse ou pelo teclado, e a faixa de valores pode ser definida no ajuste. Por padrão,
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 va-
lores 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 também ser manipulados manualmente. Para alterar o valor de um objeto
Adjustment, usamos
adjustment.set_value(value)
Como já dissemos, Adjustments são capazes de emitir sinais (por serem derivados da classe
Object, assim como outros widgets) e por este motivo mudanças se propagam automaticamente
quando por exemplo uma barra de rolagem conectada a outra widget é alterada; todas widgets
ajustáveis se conectam através do sinal value_changed.
6.2 Widgets de faixa de valores
Com um pouco de bagagem sobre Adjustments, podemos voltar ao tópico inicial da lição.
Como se pode imaginar, todas as widgets de faixa de valores são associadas a um objeto
Adjustment, através da qual estas calculam as dimensões da barra de rolagem.
Barra de rolagem
São os widgets mais simples desta categoria e é uma das quais mais lidamos. São apropria-
das para mudar aspectos de outras widgets, como uma lista, uma caixa de texto ou um viewport.
Para outras funcionalidades (como escolher um valor específico) é mais recomendável usar wid-
gets de escala, que são mais amigáveis e possuem mais funcionalidades.
Podemos criá-las através do seguinte comando (horizontal ou vertical):
hscroll = gtk.HSrollbar (adjustment=None)
vscroll = gtk.VSrollbar (adjustment=None)
35
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
O parâmetro pode ser um adjustment criado pela função mostrada na seção anterior. Na
omissão deste será criado um adjustment automaticamente, que pode subseqüentemente ser
obtido através de funções auxiliares.
Widget de escala
Idêntico ao exemplo dado no início da lição, widgets Scale permitem que o usuário manipule
um valor em uma faixa específica. Pode ser usado, por exemplo, para alterar o zoom de uma
página ou o contraste de uma imagem.
Estes widgets possuem 2 tipos: 1 para widgets horizontais outro para widgets verticais (a
versão 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 parâmetro adjustment? É através deste que se pode "linkar"widgets a um adjustment em
comum. Caso seja omitido, o adjustment será criado pela função com todos os valores ajustados
em 0.0, o que não é muito útil. Como o page_size pode afetar o valor máximo da widget (além do
especificado pelo parâmetro upper), é recomendado que se ajuste o page_size em 0.0 para que
o valor upper coincida com o maior valor que o usuário possa selecionar.
Opções
Algumas widgets de escala exibem o valor escolhido ao seu lado; isto pode ser feito através
da seguinte função:
scale.set_draw_value (draw_value)
Onde draw_value pode ser True ou False. O número de casas decimais exibido pode ser ajustado
através de:
scale.set_digits (digits) (o limite é 13)
Para definir a posição 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.
Política de atualização
Como você já sabe, o sinal "value_changed"é emitido quando o valor é alterado. Mas quando
exatamente é isso? A qualquer mudança? Apenas quando o usuário pára de mover a barra da
widget? Há 3 políticas de atualização:
36
CDTC Centro de Difusão 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 wid-
get não está em movimento e o usuário solta o botão do mouse;
• UPDATE_DELAYED: Emite o sinal value_changed se o usuário soltar o botão do mouse, ou
se a barra ficar parada por um curto instante.
Para ajustar uma destas políticas faça o seguinte:
range.set_update_policy (policy)
Obtendo e usando um adjustment
Às vezes o adjustment não é criado explicitamente, sendo isto feito através da criação de uma
widget que o necessita. Nestes casos podemos obter o adjustmente através 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() não 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"através de adjustment.emit("changed").)
6.3 Labels
Labels (rótulos) estão entre os widgets mais simples, no entanto são um dos mais frequente-
mente usados. Simplesmente exibem texto que não é editável pelo usuário, como o usado em
um formulário 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 posterior-
mente à sua criação:
label.set_text (str)
Da mesma forma pode-se obter o texto já contido em um label:
str = label.get_text ()
Além disso, estas widgets podem exibir texto ao longo de várias linhas quando a str os contém.
É possível também fazer com que a widget automaticamente acrescente as quebras de linha:
37
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
label.set_line_wrap (wrap)
Onde o parâmetro wrap pode ser True ou False.
Muitas outras opções são suportadas; como sempre recomenda-se referir à documentação
original:
http://www.pygtk.org/docs/pygtk/class-gtklabel.html.
6.4 Áreas com barras de rolagem
Ainda no tópico 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 usuário
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 parâmetros são os adjustments a serem usados no sentido horizontal e vertical da wid-
get. Usualmente não é necessário especificá-los.
Para definir quando as barras de rolagem deverão 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 disponível) ou POLICY_ALWAYS (sempre estará disponível).
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 lição.
O exemplo não é particularmente útil, mas ilustra bem os conceitos aprendidos.
#!/usr/bin/env python# -*- coding: latin-1 -*-import pygtk
import gtk
38
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
classJanela:
def__init__ (self):
# Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL.
self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL)
# Ajustamos alguns parâmetros referentes à janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Widgets miscelâneos")
self.janela.resize (200, 400)
# Assegura-se que a janela será fechada corretamente.
# (Lembre-se de funções 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 recém-criado adjustment
hscale = gtk.HScale(hadjustment)
vscale = gtk.HScale(vadjustment)
39
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
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()
# Contêiner 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
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
vbox.pack_start (vscale, False, False, 2)
vbox.pack_start (scrolled_window, True, True, 2)
# E adiciona o HBox com os conteúdos do botão
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
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
42
Capítulo 7
Lição 5 - Widgets miscelâneas 2
7.1 Barras de progresso
Iremos nesta lição continuar a exploração pelas widgets do GTK+. Todas estas são vistas
com bastante freqüência.
Barras de progresso
Todo usuário as conhece; são usadas para representar o processo de uma operação. Como
tudo no GTK+, são fáceis de se criar e manipular:
progressbar = gtk.ProgressBar(adjustment=None)
O parâmetro adjustment (opcional) pode receber um adjustment criado previamente. Reveja a
lição anterior se necessário.
Para alterar o valor exibido pela barra de status, usa-se
progressbar.set_fraction(fraction)
Onde fraction é um número entre 0 e 1, representando a percentagem da barra que deverá estar
preenchida.
É também possível 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 Difusão de Tecnologia e Conhecimento Brasil/DF
• PROGRESS_TOP_TO_BOTTOM: de cima para baixo.
Além de poder exibir uma fração, a barra pode também indicar que um processo está ocor-
rendo sem precisar o quanto da operação foi concluído. 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 é também conhecido como pop-up por alguns. Consiste em uma janela com
alguns elementos empacotados (um vbox (chamado vbox) para conteúdo e um hbox (chamado
action_area) para botões e ações que o usuário possa realizar). Sua criação é bastante simples:
dialog = gtk.Dialog(title=None, parent=None, flags=0, buttons=None)
Onde title é o título do Dialog, parent é a janela principal da aplicação e flags setam as várias
opções de criação, dentre elas:
• DIALOG_MODAL - Faz com que o usuário não possa manipular a janela principal, apenas
a que foi criada;
• DIALOG_DESTROY_WITH_PARENT - Força que o Dialog seja destruído 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"funcionarão
normalmente, por exemplo).
44
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
7.3 Barras de status
São widgets relativamente simples que exibem uma mensagem por vez. Servem para auxi-
liar o usuário na interação com um programa; por exemplo, quando sobrepor o mouse sobre um
ícone a barra de status pode comunicar a funcionalidade do botão. Ou então informar sobre o
progresso de um processo.
Para que permita que várias partes da aplicação utilizem a mesma barra de status, tem-se o
que se chama de identificadores de contexto, que identificam os diferentes "usuários". Ela tam-
bém 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 função, que recebe também
uma breve descrição 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 remoção da última mensagem adicionada naquele contexto é feita assim:
statusbar.pop (context_id)
E a remoção de uma mensagem específica:
statusbar.remove (context_id, message_id)
Lembre-se que a mensagem a ser exibida sempre será a última que foi adicionada (através de
push). Como se pode perceber, cada parte do programa pode interagir com a barra de status de
forma independente, já que terá seu próprio context_id.
7.4 Exemplo
Como de praxe, terminaremos esta lição de widgets com um exemplo sobre o que foi apren-
dido.
45
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Por motivos didáticos foi usado um timeout, tópico que não será visto neste curso, para
a atualização automatizada da barra de progresso. No entanto basta saber que timer = gob-
ject.timeout_add(interval, function, ...) irá executar a cada intervalo milisegundos a função func-
tion. Para que se cancele a execução de um timeout, usa-se gobject.source_remove (timer).
Ao código, 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 Difusão de Tecnologia e Conhecimento Brasil/DF
self.statusbar.pop(context_id)
gobject.source_remove (self.timer)
defbotao_popup (self, widget, dialog):
# Aborta operação do popup
dialog.destroy()
defpopup (self, data):
# Criação da janela pop-up (perceba a referência à janela que a criou)
self.dialog = gtk.Dialog ("Processando...", self.janela, gtk.DIALOG_MODAL)
# Adiciona-se um botão 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
CDTC Centro de Difusão 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 parâmetros referentes à janela:
self.janela.set_border_width (10)
self.janela.set_title (u"Widgets miscelâneos")
self.janela.resize (200, 80)
48
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
# Assegura-se que a janela será fechada corretamente.# (Lembre-se de funções lambda
# em Python!)
self.janela.connect("destroy", lambda wid: gtk.main_quit())
self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit())
# Contêiner de todos os elementos
vbox = gtk.VBox (False, 2)
# Cria o botão que iniciará a ação
button = gtk.Button (u"Faça 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 recém-criados no vbox
vbox.pack_start (button, True, True, 2)
vbox.pack_end (self.statusbar, False, False, 0)
# E adiciona o HBox com os conteúdos do botão
49
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
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 execução:
50
Capítulo 8
Lição 6 - Widgets miscelâneas 3
8.1 Menus
Em GTK+ existem várias formas possíveis de se criar menus. Neste curso iremos ver a forma
mais manual, por motivos didáticos. Os outros métodos abstraem parte do funcionamento o que
acaba sendo prejudicial para o aprendizado.
São 3 os widgets usados para se fazer uma barra de menus e submenus:
• O item de menu, que o usuário clica para realizar a ação solicitada (por exemplo "Fechar");
• O menu, que atua como contêiner para os itens de menu, e;
• A barra de menus, que serve de contêiner para cada um dos menus.
Uma abstração 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 ação solicitada pelo usuário (por
exemplo "Novo", "Recortar", "Colar"), quanto para os elementos na barra de menus (por exemplo
"Arquivo", "Editar").
Começando pelo topo, criaremos a barra de menus:
menu_bar = gtk.MenuBar()
51
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Dispensando maiores explicações, esta função cria a barra de menus, que poderá subseqüen-
temente ser adicionada a outro contêiner.
menu = gtk.Menu()
Esta função retorna uma referência para um novo menu. Não é necessário chamar a função
show(), pois serve apenas de contêiner para os itens de menu.
menu_item = gtk.MenuItem(label=None)
Finalmente, o item de menu. Este recebe um rótulo (label), que será interpretado por carac-
teres mnemônicos precedidos de "_". É necessário que se chame a função show() pra que seja
exibido. Não confunda item de menu com menu! O primeiro é o botão associado a uma ação, e
o segundo é um contêiner para itens de menu.
A adição de um item de menu ao menu é feita através do comando append:
menu.append(menu_item)
E, finalmente, a associação de ações 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 não pode ser exibido; a exibição do mesmo será
feita através de um item de menu, que será então 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 Difusão de Tecnologia e Conhecimento Brasil/DF
Finalmente, o adicionamos à barra de menus, finalizando a construção:
menu_bar.append (menu_item_arquivo)
Afinal, não foi tão difícil quanto possa parecer! Mas agora que você já entende os elementos
de construção do menu, caso deseje automatizar este procedimento, é possívei tanto escrever
funções 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
constrói 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 usuário
pode entrar com conteúdo livre (texto). Em GTK+ um tal widget é o Entry. Este permite criar um
campo simples, de apenas uma linha.
A sintaxe de criação é a seguinte:
entry = gtk.Entry (max=0)
Onde max é o limite de caracteres permitido, e o valor 0 indica a ausência da limitação. Sua
alteração é possível após a criação:
entry.set_max_length (max)
Da mesma forma é possível alterar o conteúdo (texto):
entry.set_text (text)
(Como a classe Entry é derivada da classe Editable, aquela suporta algumas funções tais
como insert_text; a lista completa pode ser visualizada em http://www.pygtk.org/docs/pygtk/class-
gtkeditable.html).
entry.set_editable(editable)
entry.set_visibility(visible)
Estes comandos permitem, respectivamente, habilitar e desabilitar a edição de seu conteúdo
por parte do usuário (onde editable pode ser True ou False), e permitir ou não a visualização do
conteúdo sendo digitado. Isto pode ser útil em campos de senhas.
53
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
8.3 Spin buttons
Este tipo de botão pode ser usado pelo usuário para se escolher entre uma faixa de valores
numéricos. Seu funcionamento rege em torno dos Adjustments; reveja a lição caso seja neces-
sário.
A criação 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 aceleração que o botão tem ao ser pres-
sionado (variando entre 0.0 e 1.0), e digits é a quantidade de casas decimais que deve ser exibida.
É possível também alterar esses valores:
spin_button.configure (adjustment, climb_rate, digits)
que obedece à mesma sintaxe descrita acima.
Da mesma forma é possível alterar apenas outros parâmetros:
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 alteração do valor também pode ser feita de forma relativa através da função 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 Difusão 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 mínimo do Adjustment;
• SPIN_END - Ajusta o valor para o máximo do Adjustment;
• SPIN_USER_DEFINED - Altera o valor pela quantidade especificada.
Algumas funções podem controlar a aparência e o comportamento do botão de forma mais
detalhada:
spin_button.set_numeric (numeric)
Se numeric for True, isto garantirá que o usuário pode digitar apenas números no spin button;
caso contrário outros caracteres poderão ser digitados.
spin_button.set_wrap (wrap)
Já este comando faz com que, caso wrap seja True, o botão retorne ao valor mínimo quando o
usuário atingir o valor máximo e vice-versa.
spin_button.set_snap_to_ticks (snap_to_ticks)
Esta função faz com que valores "quebrados"sejam arredondados para seus equivalentes mais
próximos 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 inválido (após uma alteração), e o segundo ignora erros enquanto estiver
convertendo para valor numérico.
8.4 Diálogo de seleção 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 Difusão de Tecnologia e Conhecimento Brasil/DF
Com isso em mente, os desenvolvedores do GTK+ incluiram isso como uma widget fácil de
se usar. Para criá-la:
filesel = gtk.FileSelection(title=None)
Para alterar o endereço 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 são várias as widgets que compõem o file selection dialog, é possível manipular essas
widgets "internas"normalmente. Elas seguem o seguinte padrão de nomes:
56
CDTC Centro de Difusão 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 exercício ao leitor experimentar com os widgets apresentados nesta lição, já que
o funcionamento destes é praticamente idêntico aos apresentados anteriormente.
57
Capítulo 9
Lição 7 - Controle avançado de layout
9.1 Alignment
O widget de alinhamento (Alignment) permite que se adicione um widget em uma posição e
tamanho relativo ao widget de alinhamento. Por exemplo, pode ser usado para se centralizar um
botão 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 parâmetros
especificados. Os valores são em ponto-flutuante, e devem variar entre 0.0 e 1.0. O xalign e
yalign ajustam a posição do widget no Alignment. Estas propriedades especificam a fração de
espaço vazio que deve ser adicionado ao topo (yalign) ou à esquerda (xalign) do widget inserido.
Os outros dois parâmetros (xscale e yscale) definem a quantidade de espaço vazio que deve
ser absorvido pela widget: 0.0 não absorve nenhum espaço, e 1.0 absorve todo o espaço vazio
disponível. Naturalmente se ambos xscale e yscale forem iguais a 1.0, então o uso do widget de
alinhamento perde seu sentido, já que todo espaço vazio será absorvido.
Para adicionar um (e apenas um) widget ao alinhamento, usa-se alignment.add(widget).
Screenshot para transmitir a idéia:
58
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
9.2 Contêiner Fixed
O contêiner fixo permite que se posicione widgets em uma posição, ..., fixa. Esta posição é
relativa à ponta superior esquerda. Além disso, a posição dos widgets pode ser alterada dinami-
camente.
Novamente são 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 poderão ser adicionados outros (widget). O
segundo adiciona a widget desejada (widget) ao widget fixo (fixed) na posição x e y. O terceiro
meramente muda a widget de posição.
É possível adicionar vários widgets a um layout do tipo fixo.
Veja o seguinte exemplo:
59
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Estes devem ser usados com cautela, já que algumas configurações locais (como tamanho
de fontes) serão ignorados, como a posição é absoluta.
9.3 Contêiner layout
O contêiner Layout é bastante similar ao último visto (Fixed), com a exceção de que ele im-
plementa uma área infinita (ou melhor dizendo, até 2^32 pixels, devido a uma restrição do X).
Também se assemelha a um layout Fixed adicionado a uma ScrolledWindow, mas sem as barras
de rolagem. É basicamente a mesma idéia implementada de forma um pouco diferente.
A criação é feita usando
layout = gtk.Layout (hadjustment=None, vadjustment=None)
Como se pode perceber, é possível especificar objetos do tipo Adjustment que o widget Layout
irá usar para barra de rolagem. Omiti-los significa que novos adjustments serão criados.
Para respectivamente adicionar e mover widgets, usa-se
layout.put(widget, x, y)
layout.put(widget, x, y)
O tamanho do contêiner Layout pode ser ajustado e obtido usando estes 2 comandos:
60
CDTC Centro de Difusão 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 contêiner não inclui a barra de rolagem, sendo necessário adicioná-las manu-
almente.
Veja o seguinte exemplo:
9.4 Frames
Frames normalmente são usados para agrupar widgets de forma clara e objetiva. Ao contrário
dos últimos widgets de agrupamento, este agrupa de forma visível ao usuário. Pode ser usado,
por exemplo, para separar seções em um grande formulário, ou para separar opções de partes
distintas de um programa.
Criá-los é simples:
frame = gtk.Frame (label=None)
O label é a descrição (visível) do agrupamento, que por padrão estará no canto superior esquerdo.
Pode também ser omitido. É possível também alterá-lo, através do comando
frame.set_label(label)
61
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Para mudar a posição do label, usa-se a função
frame.set_label_align (xalign, yalign)
Onde o parâmetro xalign pode variar entre 0.0 (esquerda) e 1.0 (direita). Atualmente o yalign não
é usado.
A adição 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 usuário possa controlar o tamanho de cada uma dessas áreas. O GTK+ permite que se
faça isso diretamente através de 2 funções:
hpane = gtk.HPaned()
vpane = gtk.VPaned()
A HPane() criará uma divisória 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 Difusão de Tecnologia e Conhecimento Brasil/DF
63
Capítulo 10
Lição 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 aplicações mais avançadas do Python/GTK+. Com algumas centenas de funções, boa parte
do conteúdo não foi visto porque o curso se tornaria repetitivo, mas a base para seu entendimento
pleno está presente no curso.
Algumas fontes recomendadas para o contínuo aprendizado:
http://www.pygtk.org/
http://www.pygtk.org/tutorial.html
http://www.pygtk.org/reference.html
Com isto encerra-se a matéria do curso propriamente dito.
Vale frisar que o curso foi bastante teórico, e permite ao programador entender todos os con-
ceitos e conhecer boa parte dos widgets e seu funcionamento. No entanto existem métodos mais
fáceis de se realizar a tarefa de diagramação de interfaces usando-se ferramentas tais como
Glade. Por não ser matéria do curso em si, veremos isso apenas de forma superficial.
10.2 Matéria extra: Criando interfaces gráficas usando PyGTK e
Glade
O primeiro passo é a instalação. No Debian e derivados, os pacotes necessários são python-
glade2 (contém as bibliotecas para o Python) e glade-2 (contém o construtor de interfaces). Por-
tanto como usuário 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 Difusão de Tecnologia e Conhecimento Brasil/DF
Inicialmente o Glade abre com um projeto novo e vazio. Repare que o projeto não contém
janelas ainda. Clique no ícone da janela na paleta (o primeiro ícone) que isto automaticamente
cria uma janela vazia. Em seguida, é possível alterar as propriedades do elemento recém-criado,
no caso a janela. Em "Propriedades"altere Name para JanelaPrincipal e Title para o que quiser.
Para adicionar elementos na janela, eles são "empacotados". Tendo a noção de como funci-
ona no nível do código fonte (ou seja, tendo feito o curso) o programador já tem todo o conheci-
mento que precisa para criar interfaces com facilidade.
Vamos criar uma interface muito simples, com apenas 2 widgets: um label e um botão. Por-
tanto siga os seguintes passos:
65
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
1. Clique no botão VBox (Vertical Box) na palheta;
2. Em seguida clique na janela para criar o VBox. Irá parecer uma janela solicitando o número
de células; reduza o valor para 2;
3. Clique no botão Label na palheta;
4. Clique na primeira célula do VBox recém-criado para adicioná-lo lá.
Viu? Temos um VBox com um elemento empacotado. Podemos alterar o conteúdo deste
rótulo 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 é possível alterar
muitas outras características que foram vistas ao longo do curso. Lembre-se de experimentar os
ajustes disponíveis também nas outras abas, tais como Packing.
Falta agora somente o botão; clique no seu respectivo botão na palheta e clique na segunda
célula do VBox para adicioná-lo. Em seguida altere o seu nome (Name) para botao1 e o rótulo
(Label) para "Clique em mim."
Ao término deste processo devemos ter algo assim:
66
CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF
Clique em Project –> Save para salvar o projeto em uma pasta própria. O resultado disso
serão 2 arquivos XML que descrevem a interface. Abra-os em um editor de texto para ter uma
noção de como a interface é descrita.
Ou seja, o Glade não gera código em si, e sim uma descrição. O python-glade2 foi instalado
por esse motivo: permitir com que o código faça uso de arquivos .glade.
OK, para ver a interface em funcionamento, crie um arquivo com o seguinte conteúdo:
import sys
import pygtk
67
CDTC Centro de Difusão 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 início da lição. A
primeira chamada dentro do __init__ carrega a interface contida no arquivo XML (vide documen-
tação aqui):
Este objeto respresenta uma ’instanciação’ 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 através dos nomes associados a estas na descrição XML.
A segunda carrega o widget especificado que, no caso, é uma janela. Finalmente gtk.main()
inicia a execução.
Mas e se quiséssemos usar sinais e eventos assim como fizemos até o momento? Vamos lá...
O primeiro passo é conectar o evento "destroy"da janela à função gtk.main_quit() como fize-
mos 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 "des-
troy"(disponível em GtkObject).
68
CDTC Centro de Difusão 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 botão; clique no botão "Clique em mim", e na janela Propriedades
(aba Signals) escolha o sinal "clicked". Em seguida clique em add.
69
CDTC Centro de Difusão 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 é recomendável que sigam um padrão.
Como, agora, fazer uso desses handlers? A biblioteca do glade para Python permite que isso
seja de forma fácil, atribuindo vários handlers a funções diferentes. Veja o código abaixo:
import sys
import pygtk
import gtk
import 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 Difusão de Tecnologia e Conhecimento Brasil/DF
glade_test = GladeTest()
Salve este código em um arquivo na mesma pasta do projeto Glade e execute-o. O resultado
é simples:
E como já deve ter sido possível perceber, o dicionário dic associa cada handler a uma função.
A função signal_autoconnect faz a associação automaticamente e de uma só vez.
10.3 Despedidas
Infelizmente o curso não irá se aprofundar mais do que isso em Glade, ficando isso a cargo
do leitor. Informações sobre Glade podem ser encontradas na Web; a página do próprio Glade é
um bom ponto de partida: http://glade.gnome.org/.
E com isso concluímos o curso. Boa parte da matéria foi vista, mas recomenda-se ao aluno
que nunca pare de aprender novas tecnologias e aprofundar-se nas existentes; busque cursos,
sites, leia, mas não fique parado!
Espero que tenham gostado!
71

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Zope
ZopeZope
Zope
 
Vim
VimVim
Vim
 
Tunelamento
TunelamentoTunelamento
Tunelamento
 
Ruby on rails
Ruby on railsRuby on rails
Ruby on rails
 
Samba
SambaSamba
Samba
 
Screen
ScreenScreen
Screen
 
Quanta
QuantaQuanta
Quanta
 
Xdmcp
XdmcpXdmcp
Xdmcp
 
Tcl tk
Tcl tkTcl tk
Tcl tk
 
Servidor de emails_seguro
Servidor de emails_seguroServidor de emails_seguro
Servidor de emails_seguro
 
Jdbc
JdbcJdbc
Jdbc
 
Qemu
QemuQemu
Qemu
 
Squid
SquidSquid
Squid
 
Jspservlets
JspservletsJspservlets
Jspservlets
 
Shell script
Shell scriptShell script
Shell script
 
Java Basico
Java BasicoJava Basico
Java Basico
 
Java applet
Java appletJava applet
Java applet
 
Java swing
Java swingJava swing
Java swing
 
Horde
HordeHorde
Horde
 
J2me
J2meJ2me
J2me
 

Semelhante a Aprenda Python-GTK com esta apostila gratuita

Monitoramento
MonitoramentoMonitoramento
MonitoramentoTiago
 
Java basico
Java basicoJava basico
Java basicoTiago
 
Iptables
IptablesIptables
IptablesTiago
 
Planejamento em desenvolvimento_de_sistemas
Planejamento em desenvolvimento_de_sistemasPlanejamento em desenvolvimento_de_sistemas
Planejamento em desenvolvimento_de_sistemasTiago
 
Javascript
JavascriptJavascript
JavascriptTiago
 
Linguagem c
Linguagem cLinguagem c
Linguagem cTiago
 
Postgre sql
Postgre sqlPostgre sql
Postgre sqlTiago
 
Jspservlets
JspservletsJspservlets
JspservletsTiago
 
Pascal
PascalPascal
PascalTiago
 
Instalacao xoops
Instalacao xoopsInstalacao xoops
Instalacao xoopsTiago
 
Drivers de dispostivos_linux
Drivers de dispostivos_linuxDrivers de dispostivos_linux
Drivers de dispostivos_linuxTiago
 
Nessus
NessusNessus
NessusTiago
 
Open solaris
Open solarisOpen solaris
Open solarisTiago
 
Postfix
PostfixPostfix
PostfixTiago
 
Programacao cpp
Programacao cppProgramacao cpp
Programacao cppTiago
 
Inkscape
InkscapeInkscape
InkscapeTiago
 

Semelhante a Aprenda Python-GTK com esta apostila gratuita (20)

Monitoramento
MonitoramentoMonitoramento
Monitoramento
 
Java basico
Java basicoJava basico
Java basico
 
Zope
ZopeZope
Zope
 
Iptables
IptablesIptables
Iptables
 
Planejamento em desenvolvimento_de_sistemas
Planejamento em desenvolvimento_de_sistemasPlanejamento em desenvolvimento_de_sistemas
Planejamento em desenvolvimento_de_sistemas
 
Javascript
JavascriptJavascript
Javascript
 
Linguagem c
Linguagem cLinguagem c
Linguagem c
 
Postgre sql
Postgre sqlPostgre sql
Postgre sql
 
Jspservlets
JspservletsJspservlets
Jspservlets
 
Pascal
PascalPascal
Pascal
 
Ltsp
LtspLtsp
Ltsp
 
Instalacao xoops
Instalacao xoopsInstalacao xoops
Instalacao xoops
 
Drivers de dispostivos_linux
Drivers de dispostivos_linuxDrivers de dispostivos_linux
Drivers de dispostivos_linux
 
Nessus
NessusNessus
Nessus
 
Open solaris
Open solarisOpen solaris
Open solaris
 
Plone
PlonePlone
Plone
 
Postfix
PostfixPostfix
Postfix
 
Mrtg
MrtgMrtg
Mrtg
 
Programacao cpp
Programacao cppProgramacao cpp
Programacao cpp
 
Inkscape
InkscapeInkscape
Inkscape
 

Mais de Tiago

Programacao php moodle
Programacao php moodleProgramacao php moodle
Programacao php moodleTiago
 
6572501 ldp-apostila-de-turbo-pascal
6572501 ldp-apostila-de-turbo-pascal6572501 ldp-apostila-de-turbo-pascal
6572501 ldp-apostila-de-turbo-pascalTiago
 
Guia rapido de_pascal
Guia rapido de_pascalGuia rapido de_pascal
Guia rapido de_pascalTiago
 
Python bge
Python bgePython bge
Python bgeTiago
 
Curso python
Curso pythonCurso python
Curso pythonTiago
 
Curso python
Curso pythonCurso python
Curso pythonTiago
 
Aula 01 python
Aula 01 pythonAula 01 python
Aula 01 pythonTiago
 
Threading in c_sharp
Threading in c_sharpThreading in c_sharp
Threading in c_sharpTiago
 
Retirar acentos de_determinado_texto_em_c_sharp
Retirar acentos de_determinado_texto_em_c_sharpRetirar acentos de_determinado_texto_em_c_sharp
Retirar acentos de_determinado_texto_em_c_sharpTiago
 
Remover caracteres especiais_texto_em_c_sharp
Remover caracteres especiais_texto_em_c_sharpRemover caracteres especiais_texto_em_c_sharp
Remover caracteres especiais_texto_em_c_sharpTiago
 
Obter ip da_internet_em_c_sharp
Obter ip da_internet_em_c_sharpObter ip da_internet_em_c_sharp
Obter ip da_internet_em_c_sharpTiago
 
Metodo using no_c_sharp
Metodo using no_c_sharpMetodo using no_c_sharp
Metodo using no_c_sharpTiago
 
Introdução ao c# para iniciantes
Introdução ao c# para iniciantesIntrodução ao c# para iniciantes
Introdução ao c# para iniciantesTiago
 
Interfaces windows em c sharp
Interfaces windows em c sharpInterfaces windows em c sharp
Interfaces windows em c sharpTiago
 
Filestream sistema arquivos
Filestream  sistema arquivosFilestream  sistema arquivos
Filestream sistema arquivosTiago
 
Curso linux professor rafael
Curso linux professor rafaelCurso linux professor rafael
Curso linux professor rafaelTiago
 
Curso de shell
Curso de shellCurso de shell
Curso de shellTiago
 
Controle lpt em_c_sharp
Controle lpt em_c_sharpControle lpt em_c_sharp
Controle lpt em_c_sharpTiago
 
Classes csharp
Classes csharpClasses csharp
Classes csharpTiago
 
C# o basico
C#   o basicoC#   o basico
C# o basicoTiago
 

Mais de Tiago (20)

Programacao php moodle
Programacao php moodleProgramacao php moodle
Programacao php moodle
 
6572501 ldp-apostila-de-turbo-pascal
6572501 ldp-apostila-de-turbo-pascal6572501 ldp-apostila-de-turbo-pascal
6572501 ldp-apostila-de-turbo-pascal
 
Guia rapido de_pascal
Guia rapido de_pascalGuia rapido de_pascal
Guia rapido de_pascal
 
Python bge
Python bgePython bge
Python bge
 
Curso python
Curso pythonCurso python
Curso python
 
Curso python
Curso pythonCurso python
Curso python
 
Aula 01 python
Aula 01 pythonAula 01 python
Aula 01 python
 
Threading in c_sharp
Threading in c_sharpThreading in c_sharp
Threading in c_sharp
 
Retirar acentos de_determinado_texto_em_c_sharp
Retirar acentos de_determinado_texto_em_c_sharpRetirar acentos de_determinado_texto_em_c_sharp
Retirar acentos de_determinado_texto_em_c_sharp
 
Remover caracteres especiais_texto_em_c_sharp
Remover caracteres especiais_texto_em_c_sharpRemover caracteres especiais_texto_em_c_sharp
Remover caracteres especiais_texto_em_c_sharp
 
Obter ip da_internet_em_c_sharp
Obter ip da_internet_em_c_sharpObter ip da_internet_em_c_sharp
Obter ip da_internet_em_c_sharp
 
Metodo using no_c_sharp
Metodo using no_c_sharpMetodo using no_c_sharp
Metodo using no_c_sharp
 
Introdução ao c# para iniciantes
Introdução ao c# para iniciantesIntrodução ao c# para iniciantes
Introdução ao c# para iniciantes
 
Interfaces windows em c sharp
Interfaces windows em c sharpInterfaces windows em c sharp
Interfaces windows em c sharp
 
Filestream sistema arquivos
Filestream  sistema arquivosFilestream  sistema arquivos
Filestream sistema arquivos
 
Curso linux professor rafael
Curso linux professor rafaelCurso linux professor rafael
Curso linux professor rafael
 
Curso de shell
Curso de shellCurso de shell
Curso de shell
 
Controle lpt em_c_sharp
Controle lpt em_c_sharpControle lpt em_c_sharp
Controle lpt em_c_sharp
 
Classes csharp
Classes csharpClasses csharp
Classes csharp
 
C# o basico
C#   o basicoC#   o basico
C# o basico
 

Último

DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -
DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -
DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -Aline Santana
 
ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024Jeanoliveira597523
 
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicas
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicasCenários de Aprendizagem - Estratégia para implementação de práticas pedagógicas
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicasRosalina Simão Nunes
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividadeMary Alvarenga
 
“Sobrou pra mim” - Conto de Ruth Rocha.pptx
“Sobrou pra mim” - Conto de Ruth Rocha.pptx“Sobrou pra mim” - Conto de Ruth Rocha.pptx
“Sobrou pra mim” - Conto de Ruth Rocha.pptxthaisamaral9365923
 
Governo Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 BrasilGoverno Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 Brasillucasp132400
 
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxAD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxkarinedarozabatista
 
Habilidades Motoras Básicas e Específicas
Habilidades Motoras Básicas e EspecíficasHabilidades Motoras Básicas e Específicas
Habilidades Motoras Básicas e EspecíficasCassio Meira Jr.
 
ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaJúlio Sandes
 
02. Informática - Windows 10 apostila completa.pdf
02. Informática - Windows 10 apostila completa.pdf02. Informática - Windows 10 apostila completa.pdf
02. Informática - Windows 10 apostila completa.pdfJorge Andrade
 
Manual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManuais Formação
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Centro Jacques Delors
 
GÊNERO TEXTUAL - TIRINHAS - Charges - Cartum
GÊNERO TEXTUAL - TIRINHAS - Charges - CartumGÊNERO TEXTUAL - TIRINHAS - Charges - Cartum
GÊNERO TEXTUAL - TIRINHAS - Charges - CartumAugusto Costa
 
Universidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumUniversidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumPatrícia de Sá Freire, PhD. Eng.
 
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxD9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxRonys4
 
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...ArianeLima50
 
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxOsnilReis1
 

Último (20)

DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -
DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -
DESAFIO LITERÁRIO - 2024 - EASB/ÁRVORE -
 
ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024ABRIL VERDE.pptx Slide sobre abril ver 2024
ABRIL VERDE.pptx Slide sobre abril ver 2024
 
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicas
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicasCenários de Aprendizagem - Estratégia para implementação de práticas pedagógicas
Cenários de Aprendizagem - Estratégia para implementação de práticas pedagógicas
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividade
 
“Sobrou pra mim” - Conto de Ruth Rocha.pptx
“Sobrou pra mim” - Conto de Ruth Rocha.pptx“Sobrou pra mim” - Conto de Ruth Rocha.pptx
“Sobrou pra mim” - Conto de Ruth Rocha.pptx
 
Governo Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 BrasilGoverno Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 Brasil
 
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA -
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA      -XI OLIMPÍADAS DA LÍNGUA PORTUGUESA      -
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA -
 
Orientação Técnico-Pedagógica EMBcae Nº 001, de 16 de abril de 2024
Orientação Técnico-Pedagógica EMBcae Nº 001, de 16 de abril de 2024Orientação Técnico-Pedagógica EMBcae Nº 001, de 16 de abril de 2024
Orientação Técnico-Pedagógica EMBcae Nº 001, de 16 de abril de 2024
 
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxAD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
 
Habilidades Motoras Básicas e Específicas
Habilidades Motoras Básicas e EspecíficasHabilidades Motoras Básicas e Específicas
Habilidades Motoras Básicas e Específicas
 
ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
 
02. Informática - Windows 10 apostila completa.pdf
02. Informática - Windows 10 apostila completa.pdf02. Informática - Windows 10 apostila completa.pdf
02. Informática - Windows 10 apostila completa.pdf
 
Manual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envio
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029
 
GÊNERO TEXTUAL - TIRINHAS - Charges - Cartum
GÊNERO TEXTUAL - TIRINHAS - Charges - CartumGÊNERO TEXTUAL - TIRINHAS - Charges - Cartum
GÊNERO TEXTUAL - TIRINHAS - Charges - Cartum
 
Universidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumUniversidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comum
 
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxD9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
 
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
 
Em tempo de Quaresma .
Em tempo de Quaresma                            .Em tempo de Quaresma                            .
Em tempo de Quaresma .
 
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
 

Aprenda Python-GTK com esta apostila gratuita

  • 2. Sumário I Sobre essa Apostila 3 II Informações Básicas 5 III Python-GTK 10 1 O que é o Curso 11 2 Plano de ensino 12 2.1 Objetivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2 Público Alvo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 Pré-requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.4 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.5 Metodologia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.6 Cronograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.7 Programa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.8 Avaliação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.9 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3 Lição 1 - Apresentando PyGTK 15 3.1 Um breve histórico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2 Primeiros passos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.3 Conferindo a instalação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4 Lição 2 - Apresentando Widgets, Signals e Callbacks 19 4.1 Conceitos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.2 Um exemplo prático . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5 Lição 3 - Widgets elementares 24 5.1 Empacotando widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.2 O widget do botão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 6 Lição 4 - Widgets miscelâneas 1 34 6.1 Adjustments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 6.2 Widgets de faixa de valores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 6.3 Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 6.4 Áreas com barras de rolagem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 6.5 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 1
  • 3. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 7 Lição 5 - Widgets miscelâneas 2 43 7.1 Barras de progresso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 7.2 Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7.3 Barras de status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 7.4 Exemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 8 Lição 6 - Widgets miscelâneas 3 51 8.1 Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 8.2 Entrada de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 8.3 Spin buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 8.4 Diálogo de seleção de arquivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 9 Lição 7 - Controle avançado de layout 58 9.1 Alignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 9.2 Contêiner Fixed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 9.3 Contêiner layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 9.4 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 9.5 Paned Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 10 Lição 8 - Progredindo com PyGTK 64 10.1 Progredindo com PyGTK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 10.2 Matéria extra: Criando interfaces gráficas usando PyGTK e Glade . . . . . . . . . . 64 10.3 Despedidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 2
  • 4. Parte I Sobre essa Apostila 3
  • 5. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Conteúdo O conteúdo dessa apostila é fruto da compilação de diversos materiais livres publicados na in- ternet, disponíveis em diversos sites ou originalmente produzido no CDTC em http://www.cdtc.org.br. O formato original deste material bem como sua atualização está disponível dentro da licença GNU Free Documentation License, cujo teor integral encontra-se aqui reproduzido na seção de mesmo nome, tendo inclusive uma versão traduzida (não oficial). A revisão e alteração vem sendo realizada pelo CDTC (suporte@cdtc.org.br) desde outubro de 2006. Críticas e sugestões construtivas são bem-vindas a qualquer tempo. Autores A autoria deste é de responsabilidade de Pedro Guerra Brandão. O texto original faz parte do projeto Centro de Difusão de Tecnologia e Conhecimento, que vem sendo realizado pelo ITI (Instituto Nacional de Tecnologia da Informação) 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 país. Informações adicionais podem ser obtidas através do email ouvidoria@cdtc.org.br, ou da home page da entidade, através da URL http://www.cdtc.org.br. Garantias O material contido nesta apostila é isento de garantias e o seu uso é de inteira responsabi- lidade do usuário/leitor. Os autores, bem como o ITI e seus parceiros, não se responsabilizam direta ou indiretamente por qualquer prejuízo oriundo da utilização do material aqui contido. Licença Copyright ©2006, Instituto Nacional de Tecnologia da Informação (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 APOS- TILA. A copy of the license is included in the section entitled GNU Free Documentation License. 4
  • 7. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Sobre o CDTC Objetivo Geral O Projeto CDTC visa a promoção e o desenvolvimento de ações que incentivem a dissemina- ção de soluções que utilizem padrões abertos e não proprietários de tecnologia, em proveito do desenvolvimento social, cultural, político, tecnológico e econômico da sociedade brasileira. Objetivo Específico Auxiliar o Governo Federal na implantação do plano nacional de software não-proprietário e de código fonte aberto, identificando e mobilizando grupos de formadores de opinião dentre os servidores públicos e agentes políticos da União Federal, estimulando e incentivando o mercado nacional a adotar novos modelos de negócio da tecnologia da informação e de novos negócios de comunicação com base em software não-proprietário e de código fonte aberto, oferecendo treinamento específico para técnicos, profissionais de suporte e funcionários públicos usuários, criando grupos de funcionários públicos que irão treinar outros funcionários públicos e atuar como incentivadores e defensores de produtos de software não proprietários e código fonte aberto, ofe- recendo conteúdo técnico on-line para serviços de suporte, ferramentas para desenvolvimento de produtos de software não proprietários e de seu código fonte livre, articulando redes de terceiros (dentro e fora do governo) fornecedoras de educação, pesquisa, desenvolvimento e teste de pro- dutos de software livre. Guia do aluno Neste guia, você terá reunidas uma série de informações importantes para que você comece seu curso. São elas: • Licenças para cópia de material disponível • Os 10 mandamentos do aluno de Educação a Distância • Como participar dos foruns e da wikipédia • Primeiros passos É muito importante que você entre em contato com TODAS estas informações, seguindo o roteiro acima. Licença Copyright ©2006, Instituto Nacional de Tecnologia da Informação (cdtc@iti.gov.br). 6
  • 8. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF É dada permissão para copiar, distribuir e/ou modificar este documento sob os termos da Licença de Documentação Livre GNU, Versão 1.1 ou qualquer versão posterior públicada pela Free Software Foundation; com o Capitulo Invariante SOBRE ESSA APOSTILA. Uma cópia da licença está inclusa na seção entitulada "Licença de Docu- mentação Livre GNU". Os 10 mandamentos do aluno de educação online • 1. Acesso à Internet: ter endereço eletrônico, um provedor e um equipamento adequado é pré-requisito para a participação nos cursos a distância. • 2. Habilidade e disposição para operar programas: ter conhecimentos básicos de Informá- tica é necessário para poder executar as tarefas. • 3. Vontade para aprender colaborativamente: interagir, ser participativo no ensino a distân- cia conta muitos pontos, pois irá colaborar para o processo ensino-aprendizagem pessoal, dos colegas e dos professores. • 4. Comportamentos compatíveis com a etiqueta: mostrar-se interessado em conhecer seus colegas de turma respeitando-os e fazendo ser respeitado pelo mesmo. • 5. Organização pessoal: planejar e organizar tudo é fundamental para facilitar a sua revisão e a sua recuperação de materiais. • 6. Vontade para realizar as atividades no tempo correto: anotar todas as suas obrigações e realizá-las em tempo real. • 7. Curiosidade e abertura para inovações: aceitar novas idéias e inovar sempre. • 8. Flexibilidade e adaptação: requisitos necessário à mudança tecnológica, aprendizagens e descobertas. • 9. Objetividade em sua comunicação: comunicar-se de forma clara, breve e transparente é ponto - chave na comunicação pela Internet. • 10. Responsabilidade: ser responsável por seu próprio aprendizado. O ambiente virtual não controla a sua dedicação, mas reflete os resultados do seu esforço e da sua colaboração. Como participar dos fóruns e Wikipédia Você tem um problema e precisa de ajuda? Podemos te ajudar de 2 formas: A primeira é o uso dos fóruns de notícias e de dúvidas gerais que se distinguem pelo uso: . O fórum de notícias tem por objetivo disponibilizar um meio de acesso rápido a informações que sejam pertinentes ao curso (avisos, notícias). As mensagens postadas nele são enviadas a 7
  • 9. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF todos participantes. Assim, se o monitor ou algum outro participante tiver uma informação que interesse ao grupo, favor postá-la aqui. Porém, se o que você deseja é resolver alguma dúvida ou discutir algum tópico específico do curso. É recomendado que você faça uso do Forum de dúvidas gerais que lhe dá recursos mais efetivos para esta prática. . O fórum de dúvidas gerais tem por objetivo disponibilizar um meio fácil, rápido e interativo para solucionar suas dúvidas e trocar experiências. As mensagens postadas nele são enviadas a todos participantes do curso. Assim, fica muito mais fácil obter respostas, já que todos podem ajudar. Se você receber uma mensagem com algum tópico que saiba responder, não se preocupe com a formalização ou a gramática. Responda! E não se esqueça de que antes de abrir um novo tópico é recomendável ver se a sua pergunta já foi feita por outro participante. A segunda forma se dá pelas Wikis: . Uma wiki é uma página web que pode ser editada colaborativamente, ou seja, qualquer par- ticipante pode inserir, editar, apagar textos. As versões antigas vão 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 "Wikipé- dia", uma experiência grandiosa de construção de uma enciclopédia de forma colaborativa, por pessoas de todas as partes do mundo. Acesse-a em português pelos links: • Página principal da Wiki - http://pt.wikipedia.org/wiki/ Agradecemos antecipadamente a sua colaboração com a aprendizagem do grupo! Primeiros Passos Para uma melhor aprendizagem é recomendável que você siga os seguintes passos: • Ler o Plano de Ensino e entender a que seu curso se dispõe a ensinar; • Ler a Ambientação do Moodle para aprender a navegar neste ambiente e se utilizar das ferramentas básicas do mesmo; • Entrar nas lições seguindo a seqüência descrita no Plano de Ensino; • Qualquer dúvida, reporte ao Fórum de Dúvidas Gerais. Perfil do Tutor Segue-se uma descrição do tutor ideal, baseada no feedback de alunos e de tutores. O tutor ideal é um modelo de excelência: é consistente, justo e profissional nos respectivos valores e atitudes, incentiva mas é honesto, imparcial, amável, positivo, respeitador, aceita as idéias dos estudantes, é paciente, pessoal, tolerante, apreciativo, compreensivo e pronto a ajudar. 8
  • 10. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF A classificação por um tutor desta natureza proporciona o melhor feedback possível, é crucial, e, para a maior parte dos alunos, constitui o ponto central do processo de aprendizagem.’ Este tutor ou instrutor: • fornece explicações claras acerca do que ele espera, e do estilo de classificação que irá utilizar; • gosta que lhe façam perguntas adicionais; • identifica as nossas falhas, mas corrige-as amavelmente’, diz um estudante, ’e explica por- que motivo a classificação foi ou não foi atribuída’; • tece comentários completos e construtivos, mas de forma agradável (em contraste com um reparo de um estudante: ’os comentários deixam-nos com uma sensação de crítica, de ameaça e de nervossismo’) • dá uma ajuda complementar para encorajar um estudante em dificuldade; • esclarece pontos que não foram entendidos, ou corretamente aprendidos anteriormente; • ajuda o estudante a alcançar os seus objetivos; • é flexível quando necessário; • mostra um interesse genuíno em motivar os alunos (mesmo os principiantes e, por isso, talvez numa fase menos interessante para o tutor); • escreve todas as correções de forma legível e com um nível de pormenorização adequado; • acima de tudo, devolve os trabalhos rapidamente; 9
  • 12. Capítulo 1 O que é o Curso Python é uma linguagem interpretada, orientada a objetos, extensível e de fácil utilização. GTK+ (Gimp Tool Kit) é uma biblioteca para criar interfaces gráficas. Para utilizá-las em conjunto, foi criado o PyGTK, que consiste em uma série de módulos para prover uma interface ao Python para acesso ao GTK, possibilitando ao desenvolvedor a criação de sistemas com interfaces gráficas riquíssimas. 11
  • 13. Capítulo 2 Plano de ensino 2.1 Objetivo Habilitar técnicos e programadores a usarem a biblioteca PyGTK, para Python. 2.2 Público Alvo Técnicos e Programadores que desejem trabalhar com PyGTK. 2.3 Pré-requisitos Os usuários deverão ser, necessariamente, indicados por empresas públicas e ter certo co- nhecimento da linguagem Python. É recomendável um conhecimento mínimo nos recursos es- pecíficos da linguagem (por exemplo dicionários e tuplas). Noções de orientação a objetos em Python também são recomendáveis. Não é necessário conhecimento prévio de GTK+. 2.4 Descrição O curso de Introdução ao Python será realizado na modalidade EAD e utilizará a plataforma Moodle como ferramenta de aprendizagem. Ele é composto de um módulo de aprendizado que será dado na primeira semana e um módulo de avaliação que será dado na segunda semana. O material didático estará disponível on-line de acordo com as datas pré-estabelecidas no calendá- rio. A versão utilizada para o PyGTK será a 2.10. 2.5 Metodologia O curso está dividido da seguinte maneira: 12
  • 14. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 2.6 Cronograma • 1ª Semana - Introdução + Conceitos básicos; • 2ª Semana - Conceitos avançados. Todo o material está no formato de livro, e estará disponível ao longo do curso. O livro poderá ser acessado quantas vezes forem necessárias. Aconselhamos a leitura de "Ambientação do Moodle", para que você conheça o produto de Ensino a Distância, evitando dificuldades advindas do "desconhecimento"sobre o mesmo. Ao final de cada semana do curso será disponibilizada a prova referente ao módulo estudado anteriormente que também conterá perguntas sobre os textos indicados. Utilize o material de cada semana e os exemplos disponibilizados para se preparar para prova. Os instrutores estarão à sua disposição ao longo de todo curso. Qualquer dúvida deve ser disponibilizada no fórum ou enviada por e-mail. Diariamente os monitores darão respostas e es- clarecimentos. 2.7 Programa O curso oferecerá o seguinte conteúdo: Semana 1: • Visão Geral e Histórico; • Introdução; • Um breve exemplo; • Modificando parâmetros; • Callbacks; • Widgets básicos. Semana 2: 1. Outras widgets; 2. Aperfeiçoando o controle de layout; 3. Automatizando o processo de criação de interfaces. 2.8 Avaliação Toda a avaliação será feita on-line. Aspectos a serem considerados na avaliação: • Iniciativa e autonomia no processo de aprendizagem e de produção de conhecimento; • Capacidade de pesquisa e abordagem criativa na solução dos problemas apresentados. 13
  • 15. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Instrumentos de avaliação: • Participação ativa nas atividades programadas; • Avaliação ao final do curso; • O participante fará várias avaliações referente ao conteúdo do curso. Para a aprovação e obtenção do certificado o participante deverá obter nota final maior ou igual a 6.0 de acordo com a fórmula abaixo: • Nota Final = ((ML x 7) + (AF x 3)) / 10 = Média aritmética das lições; • AF = Avaliações. 2.9 Bibliografia • Site official: http://www.python.org • Guia: http://www.pygtk.org/pygtk2tutorial/index.html 14
  • 16. Capítulo 3 Lição 1 - Apresentando PyGTK 3.1 Um breve histórico Embora o curso assuma um certo conhecimento de Python, não é necessário que o aluno tenha experiência com GTK+. Entretanto, isto não nos impede de oferecer uma visão geral de todos os componentes envolvidos. GTK+ O GIMP Toolkit, popularmente conhecido por GTK+, é um dos mais famosos toolkits voltados para a criação de interfaces gráficas (referidas GUIs daqui em diante). O que, então, 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 além. O GTK+ é um dos pilares do famoso ambiente de janelas GNOME, portanto aplicações base- adas nesta biblioteca podem ser facilmente identificadas pelo visual em comum. Seus autores incluem Spencer Kimball, Peter Mattis e Josh MacDonald, todos os quais traba- lhavam na Universidade de Berkeley à época de criação do GTK+/GIMP. 15
  • 17. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Os menus, botões, formulários, dropdowns e outros elementos da janela (widgets) possuem um visual bastante padronizado, mesmo entre os vários temas disponíveis no GTK+ (acima re- presentado está o tema padrão da distribuição Ubuntu). Python Python é uma linguagem de programação de alto nível orientada a objetos. Seu criador, Guido van Rossum, a criou em 1991 com o objetivo de enfatizar o esforço do programador sobre o es- forço computacional, tornando-se uma linguagem de fácil aprendizagem. Além do mais, Python se difere de outras linguagens no quesito simplicidade e legibilidade. Por exemplo, a indentação do código é de prima importância para que o código execute correta- mente, o que conseqüentemente facilita bastante a sua compreensão e padroniza os programas com um look similar. O caractere ; não é necessário para indicar o término de um comando, servindo a quebra de linha (n) para tal. Quanto ao aspecto de simplicidade, isto apenas se aplica ao núcleo da linguagem. Há uma vasta quantidade de bibliotecas disponíveis, inclusive distribuídas com o Python. Uma destas, aliás, é o... 16
  • 18. CDTC Centro de Difusão 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+ através da biblioteca PyGTK. Dispensando explicações sobre a origem de seu nome, partiremos para um overview geral. O PyGTK é um conjunto de wrappers (vulgarmente "envoltórios") para a biblioteca GTK+. As- sim como o Python, o PyGTK é software livre, no entanto é distribuído sob a licença LGPL. É de autoria de um dos desenvolvedores do GNOME, James Henstridge, e hoje possui uma equipe maior, inclusive com grande participação da comunidade através de patches e bug reports. Um dos méritos do PyGTK é ter sido escolhido como o ambiente de escolha para aplicações rodando nos sistemas do projeto One Laptop Per Child. Além 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. Instação O Linux é, decididamente, a plataforma ideal para este tipo de desenvolvimento e é a que nós recomendamos. Não obstante, usuários de Windows podem seguir com o curso, assim como os de Mac OS X. Apenas a etapa de instalação deverá diferir do que está apresentado no curso (Devido à indisponibilidade de recursos, a tarefa de instalçao será deixada por conta do usuário). Linux Talvez até excessivamente simples, para se instalar o PyGTK nas distribuições Debian e de- rivados (tais como Ubuntu), basta instalar o pacote python-gtk2: apt-get install python-gtk2 Isto irá instalar as bibliotecas necessárias. Caso seja solicitado para instalar pacotes depen- dentes, aceite. Caso esteja usando outra distribuição, procure um pacote com este nome ou pygtk. 17
  • 19. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 3.3 Conferindo a instalação OK, tecnicamente estamos prontos para seguir em frente e aprendermos os conceitos. Mas primeiro vamos verificar se a etapa de instalação realmente foi concluída com êxito. Crie um arquivo com o seguinte código 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 dúvida ao fórum! Não será possível prosseguir com o curso se este exemplo não funcionar. Não se preocupe com o código, iremos detalhá-lo mais adiante. Perceba que este exemplo apenas exibe uma janela vazia. Nem mesmo o botão de fechá-la funciona. Veremos os motivos mais adiante. 18
  • 20. Capítulo 4 Lição 2 - Apresentando Widgets, Signals e Callbacks 4.1 Conceitos básicos Antes de prosseguirmos com os exemplos, iremos dar uma breve olhada nos conceitos que serão explorados. Estes são de crucial importância para o entendimento pleno da matéria. Usuá- rios que não possuem experiência prévia com GTK+: leiam esta página atenciosamente. Widgets Um conceito extremamente simples; derivado de window gadets (apetrechos de janela), o termo pode representar qualquer elemento de uma janela, tais como botões, barras de rolagem, menus dropdown, campo de texto, barra de título, barra de ferramentas e qualquer outra parafer- nália 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 função correspondente. Este conceito é denominado sinal (entretanto este conceito é meramente seme- lhante aos signals Unix, a implementação é bastante diferente). Quando ocorre um evento, como o apertar de um botão, o widget irá emitir um sinal. Os sinais variam de widget para widget. Por exemplo, o botão herda sinais de várias classes: • gobject.GObject: "activate", "clicked", "enter", "leave", "pressed"e "released"; • gtk.Object: "destroy"; • gtk.Widget: "accel-closures-changed", "button-press-event", "button-release-event", "can- activate-accel", "child-notify", dentre muitas, muitas outras; 19
  • 21. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF • gtk.Container: "add", "check-resize", "remove", "set-focus-child". Para o exemplo do botão, 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 possível de sinais é imensa para um dado widget, e neste curso iremos ver apenas os signals mais freqüentemente utilizados. Callback Quando um sinal ocorre, uma função callback pode ser acionada. Esta função 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, então, associar uma função callback a um signal? Para tal, os objetos em GTK possuem a função connect: handler_id = object.connect (name, func, func_data) Nesta linha, object é a instância do GtkWidget que estará emitindo o sinal, e o primeiro argu- mento (name) indica o nome do sinal que irá acionar o callback (por exemplo "clicked"ou "des- troy"). O segundo argumento (func) indica a função (callback) que deverá ser acionada. Repare que o argumento é o *objeto* da função, e não o seu nome. No terceiro argumento, estão os dados que serão repassados para a função. Portanto o callback deverá ter o seguinte cabeçalho: def callback_func (widget, callback_data) O primeiro parâmetro será um ponteiro para a widget que emitiu o sinal, e o segundo parâme- tro um ponteiro para os dados definidos na chamada do connect. Naturalmente, se a função callback for definida em um método, sua forma geral será: def callback_func_method (self, widget, callback_data) Onde self representa a instância do object acionando o método. (Existem exceções quanto aos seus argumentos, mas de forma geral serão estes.) Juntos, estes dois conceitos (signals e callbacks) formam boa parte dos fundamentos por trás do GTK+. Eventos Além dos sinais, existem também eventos, que refletem o mecanismo de eventos do X. São muito similares a sinais, no sentido que callbacks também podem ser associados a estes. Re- fletem eventos tais como o requisitado fechamento de um programa, ou o clique do mouse (ou duplo-, triplo-clique). No entanto, o cabeçalho de suas funções callback é um pouco diferente: def callback_func (widget, event, callback_data) ou, no caso de uma função callback definida em um método: def callback_func_method (self, widget, event, callback_data) 20
  • 22. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Como fazer para conectar uma função callback a um evento? Usando connect: handler_id = object.connect (name, func) Por exemplo, para um botão 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 função: button_click_event (widget, event, callback_data) O valor que esta função 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 não deverá propagar (isto é, se houver mais de um callback associado a um evento). Se retornar False, então o evento será propagado. Se isto ainda está um pouco nebuloso, não se preocupe. Exemplos tornarão os conceitos bem mais claros. Desconectando callbacks É claro, também é possível desassociar um callback de um sinal ou um evento. O comando a ser usado é o seguinte: object.disconnect (handler_id) 4.2 Um exemplo prático Agora que temos um embasamento teórico podemos partir para exemplos. Crie um arquivo com o nome botao1.py com o seguinte conteúdo: #!/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 através da geração de uma instância da classe Window. """ self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL) """ Ajustamos alguns parâmetros referentes à janela: - Ajusta o espaçamento da borda para 10 (espaço entre borda e os widgets) - Seta o título da janela 21
  • 23. CDTC Centro de Difusão 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 não fosse feito, o programa continuaria sua execução mesmo após o fechamento da janela """ self.janela.connect ("delete_event", self.delete_event) """ Em seguida cria-se um botão (perceba que é a isntância de uma classe. """ self.botao = gtk.Button ("Hey there") """ IMPORTANTÍSSIMO: (quase) todo elemento deve ser explicitamente exibido para que apareça na tela. """ self.botao.show () """ Adiciona o botão à janela. Para adicionar mais elementos será necessário 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 código é bastante intuitiva; a criação da janela, atribuição de parãmetros, cria- ção do botão. Há dois elementos importantes neste exemplo: o callback e as chamadas a show(). 22
  • 24. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF O método show() causa uma widget a ser exibida assim que possível. Antes de se chamar este método a widget não será mostrada! Naturalmente, para que uma widget seja visualizada, é necessário também que todos os contêineres da widget também sejam explicitamente mostrados. Quando um contêiner "toplevel"(que contém 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 começar das widgets internas até chegar nas widgets externas; caso contrário o usuário irá ver a atualização dos componentes dependendo da complexidade gráfica 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 solicitação de fe- chamento do programa. Isto pode ocorrer quando o usuário clica no X para fechar, ou pelo gerenciador de tarefas. Em todo caso, se não tratarmos este evento a widget em questão (no caso a janela em si) será finalizada, no entanto o gtk.main() continuará sua execução (Tente isto: remova o self.janela.connect e veja o que ocorre depois de fechada a janela). Por esse motivo é necessário explicitamente executar gtk.main_quit(). O dado passado pelo delete_event (no quarto parâmetro da função callback) é None e portanto é ignorado pela função callback. Você consegue ver a utilidade disto? Nem sempre que o usuário fecha uma janela ele neces- sariamente teve tal intenção. 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 responsável por essas ações. 23
  • 25. Capítulo 5 Lição 3 - Widgets elementares 5.1 Empacotando widgets Até o momento trabalhamos com apenas uma widget na janela principal. Como fazer para agrupá-las? Há várias formas de fazê-lo; a mais comum delas são caixas (boxes). Boxes Boxes são contêineres 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, depen- dendo da forma como sejam criados. É comum usar uma combinação de boxes (boxes dentro de boxes) para criar o efeito desejado. Como é de se esperar, para criar um HBox basta gerar uma instância de gtk.HBox(). Para adicionar elementos a um box, usa-se o método pack_start() e pack_end(), onde o primeiro in- sere da esquerda para a direita e o último da direita para a esquerda. Boxes podem agrupar tanto widgets quanto outros boxes. Vale frisar que botões são contêineres por si só, mas normalmente usa-se apenas um label dentro do botão. Como criá-los? O cabeçalho da HBox() está definido da seguinte forma: gtk.HBox (homogeneous = False, spacing = 0) Se o primeiro parâmetro for True, isto garantirá que todos os elementos tenham exatamente a mesma largura. O segundo parâmetro especifica o espaçamento entre os elementos. Além disso, a forma como se agrupa os elementos também altera a aparência geral do layout: box.pack_start(child, expand=True, fill=True, padding=0) 24
  • 26. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Box é o container onde o widget será empacotado e o parâmetro child deve ser o objeto do widget a ser empacotado. Os outros parâmetros controlam como os widgets inseridos se adaptarão ao box (ou vice-versa): • Expand define se o objeto se ajustará para ocupar todo o espaço disponível no widget (True) ou se o box se reduzirá ao tamanho dos widgets (False). Se isto for False, é possível manter todos os widgets alinhados no canto direito ou esquerdo do box; • O parâmetro fill somente tem efeito se o expand for false; neste caso, ele controla se o es- paço remanescente no box deverá ser alocado como espaçamento entre os widgets (False) ou se os widgets receberão o espaço remanescente (True). • Finalmente padding é o espaçamento que será adicionado a ambos os lados do widget. Qual a diferença entre padding (fornecido no pack_start() ou pack_end()) e spacing (fornecido no HBox() ou VBox())? O spacing é o espaço adicionado entre os elementos, e o padding é o espaço adicionado a ambos os lados de um elemento. Toda essa teoria também 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 parâmetros referentes à janela: self.janela.set_border_width (10) self.janela.set_title (u"Botões 2") self.janela.resize (300, 50) # Em seguida cria-se os botões: 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
  • 27. CDTC Centro de Difusão 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 homogêneo (todos elementos ocupam o mesmo # espaço) com espaçamento 10 entre os elementos. self.hbox = gtk.HBox (True, 10) # Empacota os botões no HBox self.hbox.pack_start (self.botao1) self.hbox.pack_start (self.botao2) # Adiciona o botão à janela. Para adicionar mais elementos # será necessário criar um contêiner, 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 além disso, encapsulando vários boxes e criando um layout extre- mamente flexível. 26
  • 28. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 5.2 O widget do botão Vimos no exemplo anterior que botões podem ser customizados com parâmetros adicionais. Já sabemos praticamente tudo sobre botões, mas há alguns truques dos quais devemos estar cientes. A sintaxe básica para criar um botão é: button = gtk.Button(label=None, stock=None) O primeiro parâmetro especifica o texto a ser exibido (opcional) e o stock pode ser uma de várias constantes pré-definidas com padrões de botões (também opcional). O stock (STOCK_QUIT) usado no exemplo da lição anterior é um botão tipicamente usado para sair de programas. A variedade completa está disponível em http://www.pygtk.org/docs/pygtk/gtk-stock-items.html. Dica: Sendo a usabilidade um aspecto muito importante nos aplicativos de atualmente, é co- mum 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 botões vistos nesta página. Assim, ao apertar Alt+(letra sublinhada), seria como se o usuário clicasse no botão. Customizando o visual Há de se convir que as possibilidades são bastantes limitadas se não se pode ao menos criar um botão com um ícone customizado; tem de haver uma forma de se criar um botão 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 parâmetros referentes à janela: self.janela.set_border_width (10) self.janela.set_title (u"Botões 3") self.janela.resize (100, 50) # Assegura-se que a janela será fechada corretamente. # (Lembre-se de funções lambda em Python!) self.janela.connect("destroy", lambda wid: gtk.main_quit()) self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit()) 27
  • 29. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF # Em seguida cria-se o botão (perceba a ausência do label) self.botao = gtk.Button () # Cria-se o box do botão... self.box = self.xpm_label_box ("tartan.xpm", u"faça algo!") # E adiciona o HBox com os conteúdos do botão self.botao.add (self.box) # Exibe-os self.box.show() self.botao.show () # Adiciona o botão á janela. Para adicionar mais elementos # será necessário 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 não-homogêneo (o ícone é menor que o label) # e sem espaçamento. box = gtk.HBox (False, 0) # Adiciona uma pequena borda como em um botão 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
  • 30. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF def main (self): gtk.main() if __name__ == "__main__": janela = Janela() janela.main() Preste atenção ao exemplo e perceberá que não é possível criar um botão com um pixmap diferenciado "nativamente", na realidade criamos um HBox no qual estão contidos o pixmap e o label. O método que usamos, xpm_label_box, poderia com facilidade ser usado em qualquer outro elemento que possa ser um contêiner. A propósito, para se criar o pixmap podemos usar uma diversidade de programas, inclusive o open-source GIMP. Outros botões Outras formas de botões são freqüentemente vistas, como toggle buttons (que possuem um relevo para indicar se estão selecionados ou não), checkboxes (uma pequena caixa que pode ser marcada ou desmarcada) e radio buttons (conjunto de botões dos quais apenas um pode ser selecionado através de pequenas bolas). Na ausência de uma tradução melhor irei me referir aos nomes originais, em inglês. Toggle buttons Toggle buttons são derivados de botões normais e são muito similares, exceto o fato de que sempre estarão em um de dois estados (pressionado ou não), alterados através de um clique. Seu estado se altera a cada clique. Estes botões são a base para check buttons e radio buttons, com muitas similaridades na implementação. Como criar um? botao = gtk.ToggleButton(label=None) Cada widget deste tipo possui uma função get_active() que retorna se o botão está pressionado ou não; o sinal que indica que o estado de um botão foi alterado é o "toggled"; juntando as duas peças do quebra-cabeça, rapidamente descobrimos como trabalhar com as mudanças de estados: def toggle_button_callback (widget, data): if (widget.get_active()): # botão está pressionado else: # botão não está pressionado 29
  • 31. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF A função get_active() pode ser usada sempre que se precisar obter o estado do botão, sendo que esta retornará True (pressionado) ou False (não-pressionado). E como alterar o estado do botão manualmente? Usa-se o seguinte método: botao.set_active(active) Onde active pode ser True (pressionado) ou False (não-pressionado). O valor inicial (quando o botão é gerado) é False. Perceba que quando esta função for chamada, os sinais "clicked"e "toggled"serão emitidos pelo botão! Check buttons Como já foi mencionado, seu funcionamento é muito parecido com toggle buttons, e de fato, são simplesmente toggle buttons com uma aparência diferente, já que os labels ficam na lateral da "caixinha"que o usuário marca. A criação é feita da seguinte forma: botao = gtk.CheckButton(label=None) O callback de verificação 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 são similares aos check buttons, mas possuem a diferenciação de serem agru- pados de tal forma que apenas um pode estar selecionado por vez. Isto é bom quando a lista de opções é razoavelmente pequena. A criação é feita com o seguinte comando: botao = gtk.RadioButton (group=None, label=None) Perceba a existência de um argumento extra. Radio buttons requerem de um grupo para funcio- nar. 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 botão. Para adicionar mais radio buttons para o grupo, passe a referência para um radio button nas chamadas subseqüentes a gtk.RadioButton(). É também uma boa idéia explicitar qual botão deverá estar apertado inicialmente com o co- mando button.set_active(is_active) Isto funciona da mesma forma como foi descrito acima. Uma vez que radio buttons estão agrupa- dos, apenas um do grupo pode estar ativo. Por este motivo, se o usuário clicar em um, depois em 30
  • 32. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF outro botão de dado grupo, o primeiro radio button irá emitir o sinal "toggled"(já que foi desativado) e o segundo botão também irá emitir o sinal "toggled"(já que acabara de ser pressionado). Recapitulando No intuito de fixar e exemplificar o que foi visto acima, preste atenção no exemplo botao4.py. #!/usr/bin/env python # -*- coding: latin-1 -*- import pygtk import gtk class Janela: # Função callback que monitora o estado dos botões 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 parâmetros referentes à janela: self.janela.set_border_width (10) self.janela.set_title (u"Botões + botões") self.janela.resize (200, 400) # Assegura-se que a janela será fechada corretamente. # (Lembre-se de funções 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
  • 33. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 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 conteúdos do botão 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 ação: 32
  • 34. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Mensagens são emitidas no terminal a cada alteração nos botões. Repare como a criação do radio button é diferente dos demais, assim como o seu funciona- mento. 33
  • 35. Capítulo 6 Lição 4 - Widgets miscelâneas 1 6.1 Adjustments Um elemento muito frequente em interfaces com usuários é o "slider", uma barra de rolagem através da qual o usuário 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 trás de seu funcionamento. Adjustments Uma aplicação necessita reagir às ações de usuários nestes widgets; isto poderia ser feito através de um sinal emitido pela widget quando houvesse uma mudança no seu valor, no qual a widget transmite também o novo valor para a função responsável. Mas e se quiséssemos as- sociar os ajustes de várias widgets, de tal forma, que mudar o valor em uma widget alteraria outra? Uma aplicação prática para isto seria conectar as barras de rolagem de tal forma a sele- cionar o conteúdo a ser visualizado, por exemplo, de uma imagem(Será isso um presságio?). Se cada widget de ajuste tivesse de emitir um sinal a cada mudança de valor, o programador teria de escrever gerenciadores de sinais para transmitir a mudança de valor de uma widget para outra. O GTK+ nos auxilia através do objeto Adjustment, que não é uma widget, mas uma forma através da qual widgets podem transmitir informações sobre ajustes de uma forma abstrata e flexível. Além de guardarem parâmetros de configuração e valores de widgets (ou várias delas), Adjustments podem emitir sinais, assim como widgets convencionais, e isso pode ser usado para propagar informações entre várias widgets separadas. Você já conhece bem esse tipo de widget; são barras de progresso, janelas com barra de rolagem, dentre outros. Criando um Adjustment A sintaxe é simples: 34
  • 36. CDTC Centro de Difusão 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 parâmetro value indica o valor inicial a ser atribuído à widget. Lower e upper são o menor e maior valores que podem ser assumidos pelo widget. Step_incr define o intervalo entre os ajus- tes, page_incr define o maior intervalo entre estes. Finalmente o page_size é o parâmetro que contém a área visível no caso de uma widget à qual se aplique. Os widgets ajustáveis podem ser divididos naqueles que necessitam de uma unidade espe- cífica (por exemplo pixels) e aqueles que usam números arbitrários. Alguns widgets que usam números arbitrários incluem a barra de rolagem e a barra de progresso. Estas podem ser ajus- tadas pelo mouse ou pelo teclado, e a faixa de valores pode ser definida no ajuste. Por padrão, 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 va- lores 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 também ser manipulados manualmente. Para alterar o valor de um objeto Adjustment, usamos adjustment.set_value(value) Como já dissemos, Adjustments são capazes de emitir sinais (por serem derivados da classe Object, assim como outros widgets) e por este motivo mudanças se propagam automaticamente quando por exemplo uma barra de rolagem conectada a outra widget é alterada; todas widgets ajustáveis se conectam através do sinal value_changed. 6.2 Widgets de faixa de valores Com um pouco de bagagem sobre Adjustments, podemos voltar ao tópico inicial da lição. Como se pode imaginar, todas as widgets de faixa de valores são associadas a um objeto Adjustment, através da qual estas calculam as dimensões da barra de rolagem. Barra de rolagem São os widgets mais simples desta categoria e é uma das quais mais lidamos. São apropria- das para mudar aspectos de outras widgets, como uma lista, uma caixa de texto ou um viewport. Para outras funcionalidades (como escolher um valor específico) é mais recomendável usar wid- gets de escala, que são mais amigáveis e possuem mais funcionalidades. Podemos criá-las através do seguinte comando (horizontal ou vertical): hscroll = gtk.HSrollbar (adjustment=None) vscroll = gtk.VSrollbar (adjustment=None) 35
  • 37. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF O parâmetro pode ser um adjustment criado pela função mostrada na seção anterior. Na omissão deste será criado um adjustment automaticamente, que pode subseqüentemente ser obtido através de funções auxiliares. Widget de escala Idêntico ao exemplo dado no início da lição, widgets Scale permitem que o usuário manipule um valor em uma faixa específica. Pode ser usado, por exemplo, para alterar o zoom de uma página ou o contraste de uma imagem. Estes widgets possuem 2 tipos: 1 para widgets horizontais outro para widgets verticais (a versão 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 parâmetro adjustment? É através deste que se pode "linkar"widgets a um adjustment em comum. Caso seja omitido, o adjustment será criado pela função com todos os valores ajustados em 0.0, o que não é muito útil. Como o page_size pode afetar o valor máximo da widget (além do especificado pelo parâmetro upper), é recomendado que se ajuste o page_size em 0.0 para que o valor upper coincida com o maior valor que o usuário possa selecionar. Opções Algumas widgets de escala exibem o valor escolhido ao seu lado; isto pode ser feito através da seguinte função: scale.set_draw_value (draw_value) Onde draw_value pode ser True ou False. O número de casas decimais exibido pode ser ajustado através de: scale.set_digits (digits) (o limite é 13) Para definir a posição 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. Política de atualização Como você já sabe, o sinal "value_changed"é emitido quando o valor é alterado. Mas quando exatamente é isso? A qualquer mudança? Apenas quando o usuário pára de mover a barra da widget? Há 3 políticas de atualização: 36
  • 38. CDTC Centro de Difusão 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 wid- get não está em movimento e o usuário solta o botão do mouse; • UPDATE_DELAYED: Emite o sinal value_changed se o usuário soltar o botão do mouse, ou se a barra ficar parada por um curto instante. Para ajustar uma destas políticas faça o seguinte: range.set_update_policy (policy) Obtendo e usando um adjustment Às vezes o adjustment não é criado explicitamente, sendo isto feito através da criação de uma widget que o necessita. Nestes casos podemos obter o adjustmente através 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() não 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"através de adjustment.emit("changed").) 6.3 Labels Labels (rótulos) estão entre os widgets mais simples, no entanto são um dos mais frequente- mente usados. Simplesmente exibem texto que não é editável pelo usuário, como o usado em um formulário 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 posterior- mente à sua criação: label.set_text (str) Da mesma forma pode-se obter o texto já contido em um label: str = label.get_text () Além disso, estas widgets podem exibir texto ao longo de várias linhas quando a str os contém. É possível também fazer com que a widget automaticamente acrescente as quebras de linha: 37
  • 39. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF label.set_line_wrap (wrap) Onde o parâmetro wrap pode ser True ou False. Muitas outras opções são suportadas; como sempre recomenda-se referir à documentação original: http://www.pygtk.org/docs/pygtk/class-gtklabel.html. 6.4 Áreas com barras de rolagem Ainda no tópico 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 usuário 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 parâmetros são os adjustments a serem usados no sentido horizontal e vertical da wid- get. Usualmente não é necessário especificá-los. Para definir quando as barras de rolagem deverão 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 disponível) ou POLICY_ALWAYS (sempre estará disponível). 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 lição. O exemplo não é particularmente útil, mas ilustra bem os conceitos aprendidos. #!/usr/bin/env python# -*- coding: latin-1 -*-import pygtk import gtk 38
  • 40. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF classJanela: def__init__ (self): # Primeiro criamos uma janela do tipo WINDOW_TOPLEVEL. self.janela = gtk.Window (gtk.WINDOW_TOPLEVEL) # Ajustamos alguns parâmetros referentes à janela: self.janela.set_border_width (10) self.janela.set_title (u"Widgets miscelâneos") self.janela.resize (200, 400) # Assegura-se que a janela será fechada corretamente. # (Lembre-se de funções 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 recém-criado adjustment hscale = gtk.HScale(hadjustment) vscale = gtk.HScale(vadjustment) 39
  • 41. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 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() # Contêiner 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
  • 42. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF vbox.pack_start (vscale, False, False, 2) vbox.pack_start (scrolled_window, True, True, 2) # E adiciona o HBox com os conteúdos do botão 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
  • 43. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 42
  • 44. Capítulo 7 Lição 5 - Widgets miscelâneas 2 7.1 Barras de progresso Iremos nesta lição continuar a exploração pelas widgets do GTK+. Todas estas são vistas com bastante freqüência. Barras de progresso Todo usuário as conhece; são usadas para representar o processo de uma operação. Como tudo no GTK+, são fáceis de se criar e manipular: progressbar = gtk.ProgressBar(adjustment=None) O parâmetro adjustment (opcional) pode receber um adjustment criado previamente. Reveja a lição anterior se necessário. Para alterar o valor exibido pela barra de status, usa-se progressbar.set_fraction(fraction) Onde fraction é um número entre 0 e 1, representando a percentagem da barra que deverá estar preenchida. É também possível 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
  • 45. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF • PROGRESS_TOP_TO_BOTTOM: de cima para baixo. Além de poder exibir uma fração, a barra pode também indicar que um processo está ocor- rendo sem precisar o quanto da operação foi concluído. 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 é também conhecido como pop-up por alguns. Consiste em uma janela com alguns elementos empacotados (um vbox (chamado vbox) para conteúdo e um hbox (chamado action_area) para botões e ações que o usuário possa realizar). Sua criação é bastante simples: dialog = gtk.Dialog(title=None, parent=None, flags=0, buttons=None) Onde title é o título do Dialog, parent é a janela principal da aplicação e flags setam as várias opções de criação, dentre elas: • DIALOG_MODAL - Faz com que o usuário não possa manipular a janela principal, apenas a que foi criada; • DIALOG_DESTROY_WITH_PARENT - Força que o Dialog seja destruído 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"funcionarão normalmente, por exemplo). 44
  • 46. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 7.3 Barras de status São widgets relativamente simples que exibem uma mensagem por vez. Servem para auxi- liar o usuário na interação com um programa; por exemplo, quando sobrepor o mouse sobre um ícone a barra de status pode comunicar a funcionalidade do botão. Ou então informar sobre o progresso de um processo. Para que permita que várias partes da aplicação utilizem a mesma barra de status, tem-se o que se chama de identificadores de contexto, que identificam os diferentes "usuários". Ela tam- bém 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 função, que recebe também uma breve descrição 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 remoção da última mensagem adicionada naquele contexto é feita assim: statusbar.pop (context_id) E a remoção de uma mensagem específica: statusbar.remove (context_id, message_id) Lembre-se que a mensagem a ser exibida sempre será a última que foi adicionada (através de push). Como se pode perceber, cada parte do programa pode interagir com a barra de status de forma independente, já que terá seu próprio context_id. 7.4 Exemplo Como de praxe, terminaremos esta lição de widgets com um exemplo sobre o que foi apren- dido. 45
  • 47. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Por motivos didáticos foi usado um timeout, tópico que não será visto neste curso, para a atualização automatizada da barra de progresso. No entanto basta saber que timer = gob- ject.timeout_add(interval, function, ...) irá executar a cada intervalo milisegundos a função func- tion. Para que se cancele a execução de um timeout, usa-se gobject.source_remove (timer). Ao código, 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
  • 48. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF self.statusbar.pop(context_id) gobject.source_remove (self.timer) defbotao_popup (self, widget, dialog): # Aborta operação do popup dialog.destroy() defpopup (self, data): # Criação da janela pop-up (perceba a referência à janela que a criou) self.dialog = gtk.Dialog ("Processando...", self.janela, gtk.DIALOG_MODAL) # Adiciona-se um botão 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
  • 49. CDTC Centro de Difusão 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 parâmetros referentes à janela: self.janela.set_border_width (10) self.janela.set_title (u"Widgets miscelâneos") self.janela.resize (200, 80) 48
  • 50. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF # Assegura-se que a janela será fechada corretamente.# (Lembre-se de funções lambda # em Python!) self.janela.connect("destroy", lambda wid: gtk.main_quit()) self.janela.connect("delete_event", lambda a1,a2:gtk.main_quit()) # Contêiner de todos os elementos vbox = gtk.VBox (False, 2) # Cria o botão que iniciará a ação button = gtk.Button (u"Faça 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 recém-criados no vbox vbox.pack_start (button, True, True, 2) vbox.pack_end (self.statusbar, False, False, 0) # E adiciona o HBox com os conteúdos do botão 49
  • 51. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 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 execução: 50
  • 52. Capítulo 8 Lição 6 - Widgets miscelâneas 3 8.1 Menus Em GTK+ existem várias formas possíveis de se criar menus. Neste curso iremos ver a forma mais manual, por motivos didáticos. Os outros métodos abstraem parte do funcionamento o que acaba sendo prejudicial para o aprendizado. São 3 os widgets usados para se fazer uma barra de menus e submenus: • O item de menu, que o usuário clica para realizar a ação solicitada (por exemplo "Fechar"); • O menu, que atua como contêiner para os itens de menu, e; • A barra de menus, que serve de contêiner para cada um dos menus. Uma abstração 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 ação solicitada pelo usuário (por exemplo "Novo", "Recortar", "Colar"), quanto para os elementos na barra de menus (por exemplo "Arquivo", "Editar"). Começando pelo topo, criaremos a barra de menus: menu_bar = gtk.MenuBar() 51
  • 53. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Dispensando maiores explicações, esta função cria a barra de menus, que poderá subseqüen- temente ser adicionada a outro contêiner. menu = gtk.Menu() Esta função retorna uma referência para um novo menu. Não é necessário chamar a função show(), pois serve apenas de contêiner para os itens de menu. menu_item = gtk.MenuItem(label=None) Finalmente, o item de menu. Este recebe um rótulo (label), que será interpretado por carac- teres mnemônicos precedidos de "_". É necessário que se chame a função show() pra que seja exibido. Não confunda item de menu com menu! O primeiro é o botão associado a uma ação, e o segundo é um contêiner para itens de menu. A adição de um item de menu ao menu é feita através do comando append: menu.append(menu_item) E, finalmente, a associação de ações 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 não pode ser exibido; a exibição do mesmo será feita através de um item de menu, que será então 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
  • 54. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Finalmente, o adicionamos à barra de menus, finalizando a construção: menu_bar.append (menu_item_arquivo) Afinal, não foi tão difícil quanto possa parecer! Mas agora que você já entende os elementos de construção do menu, caso deseje automatizar este procedimento, é possívei tanto escrever funções 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 constrói 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 usuário pode entrar com conteúdo livre (texto). Em GTK+ um tal widget é o Entry. Este permite criar um campo simples, de apenas uma linha. A sintaxe de criação é a seguinte: entry = gtk.Entry (max=0) Onde max é o limite de caracteres permitido, e o valor 0 indica a ausência da limitação. Sua alteração é possível após a criação: entry.set_max_length (max) Da mesma forma é possível alterar o conteúdo (texto): entry.set_text (text) (Como a classe Entry é derivada da classe Editable, aquela suporta algumas funções tais como insert_text; a lista completa pode ser visualizada em http://www.pygtk.org/docs/pygtk/class- gtkeditable.html). entry.set_editable(editable) entry.set_visibility(visible) Estes comandos permitem, respectivamente, habilitar e desabilitar a edição de seu conteúdo por parte do usuário (onde editable pode ser True ou False), e permitir ou não a visualização do conteúdo sendo digitado. Isto pode ser útil em campos de senhas. 53
  • 55. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 8.3 Spin buttons Este tipo de botão pode ser usado pelo usuário para se escolher entre uma faixa de valores numéricos. Seu funcionamento rege em torno dos Adjustments; reveja a lição caso seja neces- sário. A criação 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 aceleração que o botão tem ao ser pres- sionado (variando entre 0.0 e 1.0), e digits é a quantidade de casas decimais que deve ser exibida. É possível também alterar esses valores: spin_button.configure (adjustment, climb_rate, digits) que obedece à mesma sintaxe descrita acima. Da mesma forma é possível alterar apenas outros parâmetros: 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 alteração do valor também pode ser feita de forma relativa através da função 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
  • 56. CDTC Centro de Difusão 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 mínimo do Adjustment; • SPIN_END - Ajusta o valor para o máximo do Adjustment; • SPIN_USER_DEFINED - Altera o valor pela quantidade especificada. Algumas funções podem controlar a aparência e o comportamento do botão de forma mais detalhada: spin_button.set_numeric (numeric) Se numeric for True, isto garantirá que o usuário pode digitar apenas números no spin button; caso contrário outros caracteres poderão ser digitados. spin_button.set_wrap (wrap) Já este comando faz com que, caso wrap seja True, o botão retorne ao valor mínimo quando o usuário atingir o valor máximo e vice-versa. spin_button.set_snap_to_ticks (snap_to_ticks) Esta função faz com que valores "quebrados"sejam arredondados para seus equivalentes mais próximos 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 inválido (após uma alteração), e o segundo ignora erros enquanto estiver convertendo para valor numérico. 8.4 Diálogo de seleção 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
  • 57. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Com isso em mente, os desenvolvedores do GTK+ incluiram isso como uma widget fácil de se usar. Para criá-la: filesel = gtk.FileSelection(title=None) Para alterar o endereço 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 são várias as widgets que compõem o file selection dialog, é possível manipular essas widgets "internas"normalmente. Elas seguem o seguinte padrão de nomes: 56
  • 58. CDTC Centro de Difusão 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 exercício ao leitor experimentar com os widgets apresentados nesta lição, já que o funcionamento destes é praticamente idêntico aos apresentados anteriormente. 57
  • 59. Capítulo 9 Lição 7 - Controle avançado de layout 9.1 Alignment O widget de alinhamento (Alignment) permite que se adicione um widget em uma posição e tamanho relativo ao widget de alinhamento. Por exemplo, pode ser usado para se centralizar um botão 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 parâmetros especificados. Os valores são em ponto-flutuante, e devem variar entre 0.0 e 1.0. O xalign e yalign ajustam a posição do widget no Alignment. Estas propriedades especificam a fração de espaço vazio que deve ser adicionado ao topo (yalign) ou à esquerda (xalign) do widget inserido. Os outros dois parâmetros (xscale e yscale) definem a quantidade de espaço vazio que deve ser absorvido pela widget: 0.0 não absorve nenhum espaço, e 1.0 absorve todo o espaço vazio disponível. Naturalmente se ambos xscale e yscale forem iguais a 1.0, então o uso do widget de alinhamento perde seu sentido, já que todo espaço vazio será absorvido. Para adicionar um (e apenas um) widget ao alinhamento, usa-se alignment.add(widget). Screenshot para transmitir a idéia: 58
  • 60. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 9.2 Contêiner Fixed O contêiner fixo permite que se posicione widgets em uma posição, ..., fixa. Esta posição é relativa à ponta superior esquerda. Além disso, a posição dos widgets pode ser alterada dinami- camente. Novamente são 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 poderão ser adicionados outros (widget). O segundo adiciona a widget desejada (widget) ao widget fixo (fixed) na posição x e y. O terceiro meramente muda a widget de posição. É possível adicionar vários widgets a um layout do tipo fixo. Veja o seguinte exemplo: 59
  • 61. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Estes devem ser usados com cautela, já que algumas configurações locais (como tamanho de fontes) serão ignorados, como a posição é absoluta. 9.3 Contêiner layout O contêiner Layout é bastante similar ao último visto (Fixed), com a exceção de que ele im- plementa uma área infinita (ou melhor dizendo, até 2^32 pixels, devido a uma restrição do X). Também se assemelha a um layout Fixed adicionado a uma ScrolledWindow, mas sem as barras de rolagem. É basicamente a mesma idéia implementada de forma um pouco diferente. A criação é feita usando layout = gtk.Layout (hadjustment=None, vadjustment=None) Como se pode perceber, é possível especificar objetos do tipo Adjustment que o widget Layout irá usar para barra de rolagem. Omiti-los significa que novos adjustments serão criados. Para respectivamente adicionar e mover widgets, usa-se layout.put(widget, x, y) layout.put(widget, x, y) O tamanho do contêiner Layout pode ser ajustado e obtido usando estes 2 comandos: 60
  • 62. CDTC Centro de Difusão 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 contêiner não inclui a barra de rolagem, sendo necessário adicioná-las manu- almente. Veja o seguinte exemplo: 9.4 Frames Frames normalmente são usados para agrupar widgets de forma clara e objetiva. Ao contrário dos últimos widgets de agrupamento, este agrupa de forma visível ao usuário. Pode ser usado, por exemplo, para separar seções em um grande formulário, ou para separar opções de partes distintas de um programa. Criá-los é simples: frame = gtk.Frame (label=None) O label é a descrição (visível) do agrupamento, que por padrão estará no canto superior esquerdo. Pode também ser omitido. É possível também alterá-lo, através do comando frame.set_label(label) 61
  • 63. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Para mudar a posição do label, usa-se a função frame.set_label_align (xalign, yalign) Onde o parâmetro xalign pode variar entre 0.0 (esquerda) e 1.0 (direita). Atualmente o yalign não é usado. A adição 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 usuário possa controlar o tamanho de cada uma dessas áreas. O GTK+ permite que se faça isso diretamente através de 2 funções: hpane = gtk.HPaned() vpane = gtk.VPaned() A HPane() criará uma divisória 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
  • 64. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 63
  • 65. Capítulo 10 Lição 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 aplicações mais avançadas do Python/GTK+. Com algumas centenas de funções, boa parte do conteúdo não foi visto porque o curso se tornaria repetitivo, mas a base para seu entendimento pleno está presente no curso. Algumas fontes recomendadas para o contínuo aprendizado: http://www.pygtk.org/ http://www.pygtk.org/tutorial.html http://www.pygtk.org/reference.html Com isto encerra-se a matéria do curso propriamente dito. Vale frisar que o curso foi bastante teórico, e permite ao programador entender todos os con- ceitos e conhecer boa parte dos widgets e seu funcionamento. No entanto existem métodos mais fáceis de se realizar a tarefa de diagramação de interfaces usando-se ferramentas tais como Glade. Por não ser matéria do curso em si, veremos isso apenas de forma superficial. 10.2 Matéria extra: Criando interfaces gráficas usando PyGTK e Glade O primeiro passo é a instalação. No Debian e derivados, os pacotes necessários são python- glade2 (contém as bibliotecas para o Python) e glade-2 (contém o construtor de interfaces). Por- tanto como usuário 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
  • 66. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Inicialmente o Glade abre com um projeto novo e vazio. Repare que o projeto não contém janelas ainda. Clique no ícone da janela na paleta (o primeiro ícone) que isto automaticamente cria uma janela vazia. Em seguida, é possível alterar as propriedades do elemento recém-criado, no caso a janela. Em "Propriedades"altere Name para JanelaPrincipal e Title para o que quiser. Para adicionar elementos na janela, eles são "empacotados". Tendo a noção de como funci- ona no nível do código fonte (ou seja, tendo feito o curso) o programador já tem todo o conheci- mento que precisa para criar interfaces com facilidade. Vamos criar uma interface muito simples, com apenas 2 widgets: um label e um botão. Por- tanto siga os seguintes passos: 65
  • 67. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF 1. Clique no botão VBox (Vertical Box) na palheta; 2. Em seguida clique na janela para criar o VBox. Irá parecer uma janela solicitando o número de células; reduza o valor para 2; 3. Clique no botão Label na palheta; 4. Clique na primeira célula do VBox recém-criado para adicioná-lo lá. Viu? Temos um VBox com um elemento empacotado. Podemos alterar o conteúdo deste rótulo 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 é possível alterar muitas outras características que foram vistas ao longo do curso. Lembre-se de experimentar os ajustes disponíveis também nas outras abas, tais como Packing. Falta agora somente o botão; clique no seu respectivo botão na palheta e clique na segunda célula do VBox para adicioná-lo. Em seguida altere o seu nome (Name) para botao1 e o rótulo (Label) para "Clique em mim." Ao término deste processo devemos ter algo assim: 66
  • 68. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF Clique em Project –> Save para salvar o projeto em uma pasta própria. O resultado disso serão 2 arquivos XML que descrevem a interface. Abra-os em um editor de texto para ter uma noção de como a interface é descrita. Ou seja, o Glade não gera código em si, e sim uma descrição. O python-glade2 foi instalado por esse motivo: permitir com que o código faça uso de arquivos .glade. OK, para ver a interface em funcionamento, crie um arquivo com o seguinte conteúdo: import sys import pygtk 67
  • 69. CDTC Centro de Difusão 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 início da lição. A primeira chamada dentro do __init__ carrega a interface contida no arquivo XML (vide documen- tação aqui): Este objeto respresenta uma ’instanciação’ 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 através dos nomes associados a estas na descrição XML. A segunda carrega o widget especificado que, no caso, é uma janela. Finalmente gtk.main() inicia a execução. Mas e se quiséssemos usar sinais e eventos assim como fizemos até o momento? Vamos lá... O primeiro passo é conectar o evento "destroy"da janela à função gtk.main_quit() como fize- mos 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 "des- troy"(disponível em GtkObject). 68
  • 70. CDTC Centro de Difusão 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 botão; clique no botão "Clique em mim", e na janela Propriedades (aba Signals) escolha o sinal "clicked". Em seguida clique em add. 69
  • 71. CDTC Centro de Difusão 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 é recomendável que sigam um padrão. Como, agora, fazer uso desses handlers? A biblioteca do glade para Python permite que isso seja de forma fácil, atribuindo vários handlers a funções diferentes. Veja o código abaixo: import sys import pygtk import gtk import 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
  • 72. CDTC Centro de Difusão de Tecnologia e Conhecimento Brasil/DF glade_test = GladeTest() Salve este código em um arquivo na mesma pasta do projeto Glade e execute-o. O resultado é simples: E como já deve ter sido possível perceber, o dicionário dic associa cada handler a uma função. A função signal_autoconnect faz a associação automaticamente e de uma só vez. 10.3 Despedidas Infelizmente o curso não irá se aprofundar mais do que isso em Glade, ficando isso a cargo do leitor. Informações sobre Glade podem ser encontradas na Web; a página do próprio Glade é um bom ponto de partida: http://glade.gnome.org/. E com isso concluímos o curso. Boa parte da matéria foi vista, mas recomenda-se ao aluno que nunca pare de aprender novas tecnologias e aprofundar-se nas existentes; busque cursos, sites, leia, mas não fique parado! Espero que tenham gostado! 71