Capítulo 3

Temos diferentes widgets disponíveis no toolkit tk para compor nossas interfaces visuais. Ademais, podemos criar outros escrevendo bibliotecas em C ou com o próprio tcl, como os vários megawidgets e extensões encontrados nos principais sítios dedicados ao tcl/tk na rede mundial. São famosos por exemplo o Blt, o Tix, o TkTable, o iTcl (orientado a objetos), o pacote Megawidgets, e mais recentemente o BWidgets, só para citar alguns. O núcleo do tcl/tk (tcl/tk core) define os seguintes: canvas, entry, listbox, menu, text, button, checkbutton, frame, label, menubutton, message, radiobutton, scale, scrollbar e toplevel.

  • canvas
    é o widget preferido quando queremos mostrar desenhos (em forma de vetores ou bitmaps e pixmaps), contendo listas de objetos agrupados na forma de tags, podendo também conter outros widgets embutidos (embedded).
  • text
    mostra principalmente texto, mas pode conter também outros widgets, sendo usado mais para mostrar textos, com ou sem variação de atributos; possui também tags como o canvas.
  • listbox
    uma simples lista de opcões, com vários métodos de seleção.
  • message
    usado principalmente para mostrar mensagens para o usuário.
  • label
    usado para rotular outros widgets; informativo.
  • menu
    em várias diferentes incarnações (popup, pulldown), serve para agrupar vários comandos em um só widget; geralmente disparado por um menubutton.
  • menubutton
    botão especializado para invocar menus.
  • frame
    simplesmente um container, para agrupar vários outros widgets.
  • entry
    caixa de entrada de dados.
  • button
    invoca um comando quando pressionado.
  • checkbutton
    armazena o seu estado binário (pressionado ou livre).
  • radiobutton
    semelhante a um checkbutton, mas pode ter uma variável compartilhada entre vários, cada um atribuindo à variável um valor característico.
  • scale
    uma espécie de "controle de volume", que permite entrarmos muitos valores diferentes em uma variável, deslizando um cursor; pode ter orientação horizontal ou vertical.
  • scrollbar
    mais usado para mover a vista (view), região visível de outro widget como canvas, text, listbox; com versões horizontal e vertical.
Aqui temos alguns destes widgets em um tclet. Dois radiobuttons compartilham a mesma variável, que é mostrada numa pequena entry à esquerda. Clique em cada um dos radiobuttons para verificar que o valor desta variável muda. Abaixo temos um listbox com várias linhas, cada uma sendo um ítem. Role a mensagem para poder lê-la com os scrollbars, bem como também arrastando o texto no interior com o botão central do mouse pressionado (usuários com mouse de 2 botões terão que segurar os dois botões ao mesmo tempo).

Experimente criar com o visual tcl um conjunto de 3 ou mais radiobuttons e faça com que os atributos variable indiquem a mesma variável e o atributo value valores diferentes (por exemplo, nomes de animais). Complete colocando uma entry com a mesma variável.

estruturas de controle no tcl

Para construirmos aplicações realmente interessantes, precisaremos tomar decisões ou às vezes repetir segmentos de código. Para isso, toda liguagem estruturada dispóe de estruturas de controle e o tcl não é exceção. A diferença é que o tcl permite-nos ainda criar nossas próprias estruturas, como veremos mais adiante, com os comandos uplevel e upvar. Entrementes, vejamos as construções mais clássicas.

O condicional é bem semelhante ao C. Por exemplo, if $erro exit, é um comando válido, testando a variável erro e encerrando o programa caso ela seja diferente de zero. As estruturas de controle no tcl, contudo, são procedures normais, com número de argumentos pré-determinados (ex: if <teste> <cmd>) e qualquer coisa com mais (ou menos) que estes argumentos seria um erro. Assim, os argumentos são passados usualmente como listas: a primeira sendo uma expressão (argumento para o comando expr), a segunda uma lista de comandos válida. Evidentemente, estas listas podem ser simplesmente colocadas entre chaves, como vimos no capítulo anterior. Exemplo:

if { $x == 12 } {
   puts "x é uma dúzia"
}

Entendido isso, podemos relacionar as principais estruturas de controle no tcl:

if <expr1> then <cmd1> elseif <expr2> then <cmd2> ... else <cmdN>
O condicional; o then pode ser omitido, como também o else; os elsif são opcionais. O comando <cmd1> é executado se a expressão <expr1> é verdadeira, ou seja, diferente de zero. Senão, <cmd2> será executado se <expr2> é verdadeira, etc. Se nenhuma destas for válida e o else existir, <cmdN> será executado.
while <expr> <cmd>
Executa <cmd> enquanto a expressão continuar válida (diferente de zero).
for <inicio> <teste> <proximo> <cmd>
Inicializa executando o comando <inicio>, testa se <teste> (expressão) é válida, terminando se não for. Senão, executa o comando <cmd> e, no final de cada laço, o comando <proximo>.

Existe também um iterador para listas, que repete um determinado comando para cada valor encontrado numa lista, o foreach. Vejamos através de um exemplo.

No tclet ao lado mostramos um listbox (nome .cores) inicialmente vazio. Clicando com o mouse (botão da esquerda) nele, enquanto seguramos a tecla Shift, executaremos o seguinte código:

foreach cor {azul verde laranja marron vermelho} {
  .cores insert end $cor
}

que fará a inclusão de todas as strings da lista no listbox.

Caso você este curioso, para disparar esta função associada a um evento, usamos o comando
bind .cores <Shift-1> { ...comando...} onde o comando corresponde ao dado acima. o símbolo <Shift-1> indica o evento ocorrido, que no caso é o botão 1 do mouse clicado, com o modificador Shift.

como um widget é desenhado

Entre as propriedades ou atributos de um widget mais importantes estão o highlightthickness (espessura da borda de ativação), borderwidth (largura da borda 3D), e relief (relêvo). Modificando estes atributos, definimos o desenho do widget na aplicação.

Os dois primeiros atributos são simplesmente números inteiros, enquanto que o terceiro assume um dos seguintes valores: flat. raised, sunken, ridge groove.

Veja combinações destes atributos no tclet à esquerda. O efeito de relêvo só pode ser visto se a borda (borderwidth) é diferente de zero. Experimente também mudar o foco entre os vários widgets digitando Tab no teclado e controle o highlightthickness para visualizar a mudança de cores da linha que circunda o label desenhado.

Como podemos alterar atributos de um widget já desenhado? Quando um widget é criado, o tcl define um novo comando com o nome deste widget (instância do objeto), que responde a uma série de comandos, dependendo do tipo de objeto criado. Um comando universalmente reconhecido é o config, que permite obter o valor atual de qualquer propriedade do objeto ou mesmo modificá-la.

Retorne ao tclet dado no final do capítulo 1 e execute .texto config para visualizar a configuração (atributos) do widget maior, que usamos para mostrar o resultado dos comandos introduzidos. Este widget teve o seu nome definido como .texto quando foi criado.

Tente também fazer .texto config -relief flat, por exemplo, para observar o que se modifica naquele objeto. Execute .texto config -background para obter a cor do fundo deste widget. Observe que o resultado é na forma de uma lista com valor -background background Background #d9d9d9 gray80. O último ítem desta lista é o valor atual da propriedade, e o penúltimo é o valor default.


rpragana Thu Mar 18 13:53:18 EST 1999