Capítulo 2

V eremos agora como descrever ações que serão realizadas quando um evento ocorrer com as nossas interfaces visuais. A mais simples destas é o ato de pressionarmos um botão. Mas o tcl/tk suporta uma variedade muito maior de eventos, acionados por teclas, pelo cursor do mouse (por exemplo, ao entrar ou sair de um widget), ou até mesmo por eventos "virtuais". Mais adiante, você verá uma figura que na realidade é um tclet (semelhante a um applet do java), um pequeno programa em tcl rodando no interior desta página no seu browser. Se voce não tem o tcl plugin, pegue-o em http://www.demailly.com/tcl/plugin/download.html ou não será capaz de interagir com os exercícios sugeridos neste livro.

tclet erro Quando voce estiver usando um tclet, se aparecer uma imagem como esta ao lado, é porque voce cometeu algum erro de sintaxe. Clique no botão "dismiss" e corrija o erro. Voce poderá ler a mensagem para descobrir qual a razão deste erro. Em um programa tcl normal (sem ser tclet), o erro ocasionará a criação de um toplevel reportando o erro de forma semelhante.
O clássico hello world em C pode ser implementado fácilmente em tcl, como já discutimos no capítulo anterior. Veja como fica a versão dele em um tclet. Nesse caso, o que fizemos foi substituir o comando puts "olá mundo" por um comando específico para se escrever no text widget. Este comando é insert .texto end "olá mundo (em tcl)", send .texto o nome do widget que aparece como uma "tela" na parte superior do tclet. Mas não se preocupe muito com isso agora, pois você verá adiante como utilizar com detalhes o text widget.

O que pode ser colocado como comando em um botão? Praticamente tudo! Tcl possui variáveis, funções (chamadas de procedures), estruturas de controle como if, while, for, muito semelhantes a qualquer linguagem estruturada que voce já aprendeu. Uma diferença fundamental é que as variáveis em tcl não possuem data types (tipos de dados), todas são strings (cadeias de caracteres).

A sintaxe do tcl é bastante simples. Um comando é somente uma lista de palavras separadas por espaços ou tabs (mas não por newlines, ou seja, cada comando a princípio deverá estar numa só linha). Iniciemos pelo comando set, que nos permite atribuir um valor a uma variável, ou obter o seu conteúdo:

set cidade Recife faz com que a variável cidade contenha a string Recife como valor, que pode ser recuperada pelo comando set cidade. Se a string contêm espaços, podemos incluir o seu valor entre aspas, para manter sua unidade: set estado "Rio Grande do Norte". (experimente agora mesmo estes exemplos, e crie os seus próprios, no tclet encontrado no final deste capítulo) Podemos também desejar atribuir a uma variável uma string que inclui o valor de outra variável definida anteriormente. Para isso, o operador $ prefixando o nome da váriavel previamente definida faz a substituição. Exemplo:

set pais Brasil
set nacionalidade brasileiro
set frase "Quem nasce no $pais é $nacionalidade"

Quando a variável contém apenas dígitos ou o ponto decimal, ela pode ser interpretada como numérica. O interpretador do tcl não tem idéia do que a variável contém, isso é responsabilidade do programador. Por exemplo, se solicitarmos que seja calculada uma expressão com uma variável contendo uma string não-numérica, isso acarretaria num erro de runtime, que iria mostrar-nos o toplevel discutido no início deste capítulo. Para efetuarmos cálculos, usamos o comando explícito expr com uma expressão (infixa) matemática como argumento: (neste caso espaços são permitidos porque expr concatena todos os seus argumentos)

set a 3
set b 4
expr $a*$b

irá retornar o produto destas duas variáveis. Parênteses podem ser usados para alterar a precedência dos operadores, de maneira semelhante ao usual na linguagem C. Para uma lista completa das funções matemáticas, consulta a man page do comando expr (man n expr).

substituição

Vimos que o $ realiza a substituição de nomes de variáveis pelos seus valores. Outro tipo é a substituição de comandos. Colocando um comando entre colchetes [ ... ] , o resultado deste comando será substituido pela sua ocorrência. Por exemplo:

set c [expr $a*$b] 

serviria para armazenarmos o resultado da expressão contida entre os colchetes. Sem os colchetes, a string que representa o comando é que seria armazenada, evidentemente diferente do que poderíamos desejar.

Outras vezes queremos evitar totalmente a substituição de variáveis e comandos. Colocando a string entre chaves {...} todo o seu interior é preservado, mesmo que ele contenha caracteres $ ou colchetes. Todas as estruturas de controle do tcl, bindings (associação de eventos) e listas, utilizam-se dessa propriedade. Vá ao tclet do final deste capítulo e entre:

set c {expr $a*$b}

e experimente o mesmo com aspas no lugar das chaves, e com colchetes no lugar das chaves, e veja as diferenças. Explique!

Outro tipo de substituição, é o da barra invertida, que funciona como no shell do Unix (ou como a linguagem C também). Um caracter prefixado pela barra invertida "\" tem seu uso especial removido. Isso pode ser usado para introduzir os caracteres $, {, },",[, etc, ou a própria barra, com \\ em strings, sem que o interpretador tente realizar as operações que estes caracteres especiais demandam. Alguns outros como "\n", "\f", "\t", são substituidos respectivamente por um newline, form feed, tab. Podemos também introduzir um caracter qualquer em hexadecimal com \xAB onde A e B são dígitos hexadecimais, ou em octal com "\abc" onde a, b, c são dígitos em octal. Também com a barra invertida, podemos quebrar a regra de deixar cada comando tcl em uma única linha, colocando no final de uma linha "\" seguida do newline. Este último será tratado exatamente como um espaço, permitindo-nos escrever comandos muito longos em várias linhas (útil quando editamos o noss código em um arquivo texto). Como no caso do $ e [...], as barras invertidas são substituidas se usadas entre aspas, mas não no interior de chaves.

Use o visual tcl para construir uma interface como esta ao lado. Na entry modifique o atributo textvariable para capital. Dessa forma, o valor da variável capital será continuamente mostrado nessa entry. Depois codifique em cada button o código para modificar esta variável quando cada botão for pressionado.
Uma nota sobre o design: use o gerenciador de geometria
pack, com as opções expand=1 e fill=x para ter os botões "enchendo" o espaço disponível. De outra forma cada botão ficará com um tamnho diferente, visualmente desagradável.

arrays e listas

Tcl pode ter variáveis indexadas, na forma de arrays associativos. Neste tipo de array, o índice não se limita a valores numéricos (se bem que estes podem ser usados), mas com quaisquer valores. Por exemplo, podemos armazenar o número de dias de cada mes do ano em um array indexado pelo nome do mes:

set dias(janeiro) 31
set dias(fevereiro) 28
set dias(marco) 31
set dias(abril) 30

e assim por diante. Vários comandos operam com este tipo de variável. Podemos obter o número de elementos (índices) presentes com (usando o array dias definido acima) array size dias. Podemos também obter todos os índices existentes com array names dias. E ainda, obter a lista de todos os índices seguidos dos valores, dois a dois, em forma de lista com array get dias. (Experimente no tclet do final deste capítulo.)

Uma lista em tcl é apenas uma sequência de ítens, como nos argumentos de um comando, ou as várias palavras de uma string. Na realidade, podemos empregar funções que manipulam listas também em variáveis que supomos conter uma string. O separador entre os vários ítens de uma lista é normalmente o espaço, mas para criarmos listas mais complexas (por exemplo, formadas de sub-listas), devemos usar as chaves {...} para definir sua estrutura. Como exmplo, veja uma lista de animais, agrupados em sub-listas de acordo com suas características comuns:

set animais \
{{{chipanzé gorila} baleia} {formiga aranha {borboleta mariposa}} dinossauro}

Existem muitos comandos para manipularmos listas. Para obtermos o tamanho da lista: llength animais (usando a lista acima). Os elementos de uma lista são numerados a partir de 0 (zero). Um elemento pode ser obtido pelo seu índice: lindex $animais 0, por exemplo, retornará { {chipanzé gorila} baleia }, que é uma sub-lista. Descubra o que retornará a expressão: [lindex [lindex $animais 1] 2].

Experimente introduzir variáveis com o comando set x 123 por exemplo, e visualize os valores das variáveis com set x (sem nehum valor posterior). No tcl as variáveis não possuem tipos, portanto, set x vermelho armazenaria a string "vermelho" na variável. Experimente um pouco com isso. Veja também como podemos efetuar cálculos usando o comando expr.

Os comandos que voce entrar na entry (caixa de entrada) na parte inferior, serão repetidos em vermelho escuro na "tela" acima, e a resposta do interpretador tcl (no caso o seu tcl plugin) em preto. Esta tela acima é um outro widget, tipo text. Alguns comandos (ainda não vistos) que manipulam arquivos no seu disco ou comunicam com o window manager, são desativados, por motivos de segurança. Afinal, voce não quer que o seu computador possa ser invadido por um tclet tipo "cavalo de tróia", não é mesmo?


rpragana Tue Mar 16 17:14:19 EST 199