Capítulo 5

anterior sumario proximo

Controlamos a geometria dos nossos objetos através dos geometry managers disponíveis no tk: place, pack e grid.Apesar do place ser mais fácil de usar, ele torna nossa programação mais onerosa quando temos que modificar o layout incluindo ou eliminando widgets, daí o mais popular ser o pack. O gerenciador de geometria grid é usado principalmente para produzir layouts tipo "formulário", onde podemos ter objetos ocupando uma ou mais linhas e colunas de uma "grade" invisível, com tamanho das células variável.

O comando pack posiciona widgets no seu "widget-pai" (parent), de maneira dependente da ordem que executamos o packing de cada widget. Ele funciona preenchendo a cavidade no parent, conforme a borda escolhida, que pode ser top, bottom, left ou right. Depois de cada objeto "empacotado", é subtraida uma faixa de acordo com as necessidades desse objeto, sendo o retângulo restante usado nos próximos comandos pack executados. Assim, podemos notar que a ordem de "empacotamento" influi consideravelmente no layout final. No tclet ao lado, temos 4 objetos a empacotar: uma mensagem, um bitmap (label com uma figura), um botão e uma linha separadora (frame de altura pequena). Tente empacotar em diversas ordens para entender melhor o funcionamento do pack, primeiramente sem habilitar o "expand", depois repita com o "expand" habilitado para obter melhores resultados. Use o botão desfaz para refazer tudo, várias vezes. Deixamos o fundo do toplevel na cor gray50 para produzir um contraste com os objetos posicionados.
Às vezes não conseguiremos os resultados desejados somente alterando a ordem de empacotamento, por espaço insuficiente entre um widget e o seu vizinho, por exemplo. Ou queremos fazer o texto (ou imagem) no interior do widget mais afastado de sua borda. Conseguiremos esse controle através das opcões -padx, -pady, para o espaçamento externo, e -ipadx, -ipady , para o espaçamento interno do objeto. Experimente ao lado.

Interfaces mais complexas podem usar containment, isto é, frames, para agruparem vários widgets e os tratarem como uma unidade. Assim, por exemplo, vários botões formando um "painel de controle" podem ser empacotados (com -expand 1 e -padx, -pady de valores suficientes) no interior de um frame, e este por sua vez tratado como um novo "megawidget" que será empacotado na nossa interface. Podemos também combinar vários geometry managers, um diferente em cada frame, por exemplo, desde que o interior de cada frame ou toplevel use um só geometry manager.

Um objeto pode ser posicionado em outro distinto do seu pai (parent), usando a opção -in. Entretanto, neste caso devemos ter o cuidado de certificar-nos que a ordem de stacking dos objetos é obedecida, ou seja, o widget sendo posicionado no interior de outro tem a sua stacking order maior que o usado como container. Essa stacking order é definida pela ordem de criação dos widgets, mas pode ser modificada usando os comandos raise e lower, para aumentar ou diminuir, respectivamente, esta ordem. Vejamos um exemplo:

     frame .f
     button .b
     pack .b -in .f

Este último comando funciona porque .f foi criado antes de .b.

O comando pack nos fornece também controle sobre a expansão dos widgets para preencher os espaço disponível. Já vimos que a opção -expand, usada no primeiro exemplo deste capítulo, controla o posicionamento do widget centralizando-o no espaço disponível. Usada em conjunto com -fill x, -fill y, ou -fill both (default: -fill none, sem usar o fill), podemos forçar o objeto a preencher o espaço disponível em cada uma das direções ou em ambas ao mesmo tempo, aumentando o widget. Podemos também controlar o canto ou lado que o widget será colocado (sempre considerando o retângulo disponível para este), com a opção -anchor, seguida de um parâmetro n, s, e, w, c, ou combinações como nw, se, ne, sw (n=norte, s=sul, e=leste, w=oeste, c=centro, default).

No linguajar de geometry management, o widget que contêm outros é chamado de master, enquanto que os contidos são chamados de slaves (escravos). Um widget pode ser master de outro mas não ser seu pai (parent). Isso acontece quando usamos a opção -in master no comando pack.

Experimente várias opções do comando pack com o visual tcl, e também no tclet ao lado. Depois crie um frame e use o place para posicionar alguns objetos no seu interior, mas use o pack para posicionar o objeto composto no toplevel ao lado. Veja que o espaço solicitado por um widget é respeitado até o limite do espaço disponível no seu master (ou container). Para eliminar os objetos já "empacotados" use pack forget, mas tome cuidado para não eliminar o entry, ou você terá que recarregar a página para restaurar o tclet. Para listar os objetos correntemente gerenciados por um master, você pode usar o comando pack slaves master, e para verificar a configuração atual de um widget, o comando pack info slave.

Os comandos que listam, infelizmente, não poderão ser vistos num tclet tão simples como este. Faça-o na console, usando o seu interpretador wish, ou com a excelente console TkCon.

criando formulários com o grid

O geometry manager grid posiciona objetos como uma espécie de planilha, dividindo o espáco em linhas e colunas. Podemos posicionar, por exemplo, um botão .b na linha 3 coluna 2, com o comando:

   grid .b -row 3 -column 2

O espaço das células é definido pelo maior objeto na mesma linha e na mesma coluna daquela célula. Para obrigar o widget a encher o espaço de uma célula numa determinada direção, usamos a opção -stick, seguida de n, s, e, w ou combinações. Por exemplo, para forçar um widget a ocupar todo o espaço de uma célula, a despeito do seu tamanho solicitado, fazemos: -stick nsew. Além disso, as opções -padx, -pady, -ipadx, -ipady funcionam como no pack. Podemos também fazer um widget ocupar mais de uma linha ou coluna, usando células vizinhas, pelas opções -rowspan e -columnspan.

Através dos comandos grid columnconfigure e grid rowconfigure, podemos alterar o comportamento de toda uma linha ou coluna da grade. As opções destes comandos são: -minsize, -pad e -weight. A primeira indica o menor tamanho que deverá ter essa linha ou coluna. A segunda o espaço adicional a ser colocado lateralmente (no caso de columnconfigure) ou acima e abaixo (no caso de rowconfigure). A terceira indica o aumento ou diminuiçso relativa entre colunas (ou linhas) quando a janela é redimensionada. Colunas e linhas com peso (-weight) maior recebem proporcionalmente espaçso maiores quando a janela é aumentada, na mesma proporção dos seus pesos. Estes comandos esperam o nome do widget master, o número da linha (ou coluna) sendo configurada, em seguida as opções que deejamos modificar. Sem estas opções, serão listados os valores correntes. Veja um exemplo:

  grid rowconfigure . 0 -weight 2 -minsize 30

fará a linha 0 (primeira) do toplevel "." ter o menor tamanho (no caso a altura) 30 e peso 2, o que a fará crescer o dobro do tamanho das outras (com peso default 1).

Além do comando grid forget para "esquecer" completamente de um objeto sendo gerenciado (semelhante ao pack forget), o comando grid remove serve para remover temporariamente um widget, deixando-o invisível, mas que com novo comando grid (seguido do nome do widget) é remapeado na mesma posição que ocupava anteriormente.

O pacote BLT, escrito por George Howlett tem um outro geometry manager similar ao grid, chamado table. Se voce pretende escrever aplicações comerciais, seu uso é até mais simples que o grid e o recomendamos.

Tente reproduzir a interface ao lado usando o comando grid para gerenciar os seus widgets. Faça-o com o visual tcl, como sempre, salve em um arquivo e examine atentamente o código gerado. Brinque um pouco com as opções de configuração de linhas e colunas como discutimos acima. Leia a man page do comando table do BLT para ver as diferenças entre este comando e o grid.

formulario


rpragana Sun Mar 28 13:53:50 EST 1999