você está aqui: Home  → Arquivo de Mensagens

Zenity - O diálogo --forms

Colaboração: Julio Cezar Neves

Data de Publicação: 07 de janeiro de 2019

O time de desenvolvimento do Zenity andou capengando e trompicando por um bom tempo, a prova disso é que passou um bom tempo sem lançar uma versão que merecesse o título de Major Version. A cada nova versão eu ia conferir o changelog e nada de novo ... Só correções de bugs e de segurança.

Talvez, vendo o estrondoso sucesso do YAD, que começou como um fork seu, o pessoal resolveu arregaçar as mangas e incrementar este importante software.

Foram criados alguns diálogos novos mas o que mais me empolgou foi o novo --forms e é por isso que neste artigo vou abordá-lo, até porque a literatura sobre ele ainda é muito incipiente e apanhei muito para descobrir como algumas opções funcionavam.

Vamos então abrir os trabalhos vendo as opções do dialogo --forms:

Opção Efeito
--add-entry Adicionar uma nova entrada no diálogo de formulários
--add-password Adicionar uma entrada de senha
--add-calendar Adicionar um calendário no form
--add-list=NOME Cria uma lista com o texto NOME
--list-values=LISTA Valores da lista NOME, separados por
--column-values=T1|T2...|Tn T1, T2, ..., Tn são os títulos das colunas de uma lista
--add-combo=CB Adiciona a ComboBox CB ao form
--combo-values=LISTA Lista de valores de CB separados por
--show-header Exibe os títulos das colunas criados em --column-values
--text=TEXTO Definir o texto do diálogo
--separator=SEPARADOR Definir caractere separador de saída
--forms-date-format=MODELO Definir o formato para a data devolvida

Nesta tabela que acabamos de ver, os componentes de cada uma das LISTA, são separados por uma barra vertical (|) e o MODELO da opção --forms-date-format obedece às regras de formatação do comando date.

Vamos então ver um exemplo, direto no prompt, que serve para mostrar o uso de algumas dessas opções:

$ zenity --forms --text "Reserva de passagens fake" \
    --add-entry "Nome" "" \
    --add-calendar "Data da viagem" "" \
    --add-list "Escolha o assento"  \
    --list-values $(seq -s\| 10)
Sarah Vaz|25/01/2019|3

Mais um exemplo do diálogo --forms, enfatizando a forma como as variáveis receberam os dados digitados sem ser necessário fazer muita ginástica de programação:

IFS=\| read Nom Snom Prof Usu S1 S2 Uso Data <<< "
$(zenity --forms --title='Cria usuário'  \
    --text='Dados do novo usuário'       \
    --add-entry='Primeiro nome'          \
    --add-entry=Sobrenome                \
    --add-entry=Profissão                \
    --add-entry='Nome de usuário'        \
    --add-password=Senha                 \
    --add-password='Confirme a senha'    \
    --add-combo='Tipo de uso'            \
    --combo-values=Individual\|Familiar\|\
Grupal\|Profissional                     \
    --add-calendar='Data da expiração')"

$ echo "$Nom ^ $Snom ^ $Prof ^ $Usu
> $S1 ^ $S2 ^ $Uso ^ $Data"
Ema ^ Thomas ^ Traumatologista ^ Ema Noel
12345678 ^ 12345678 ^ Grupal ^ 20/12/2018

O macete foi ter mudado o valor da variável $IFS (que foi alterado para |, que é o separador de default das saídas do Zenity), somente durante a execução do read (note que a atribuição do IFS está ligada ao read, pois não há nada entre os dois). Assim sendo, a execução do comando Zenity foi priorizada ($(...)) e redirecionada (<<<) para a entrada do read.

Como já estudamos mais ou menos metade dos diálogos/opções do Zenity, você já deve ter reparado que não importa a ordem em que vêm as opções dentro de umldc deste utilitário, no entanto caso você declare mais de uma lista ou mais de um ComboBox em um formulário, as opções que declaram seus valores (--list-values ou --combo-values) devem estar na mesma ordem dos campos e elas associados.

Para demonstrar isso, fiz os seguintes testes:

$ IFS=\| read Let Num <<< "$(zenity --forms \
    --add-combo Letras --add-combo Números  \
    --combo-values 'A|B|C|D' --combo-values '1|2|3|4')"
$ echo Letra escolhida=$Let
$ echo Número escolhido=$Num
Letra escolhida=B
Número escolhido=2

e

$ IFS=\| read Let Num <<< "$(zenity --forms     \
    --add-combo Letras --combo-values 'A|B|C|D' \
    --add-combo Números --combo-values '1|2|3|4')"
$ echo Letra escolhida=$Let
$ echo Número escolhido=$Num
Letra escolhida=B
Número escolhido=2

Ambos funcionaram a contento, com as duas ComboBoxes exibindo todas as letras e todos os números que especificamos e produzindo o formulário a seguir:

No entanto, no teste que fiz logo após, inverti a ordem da declaração dos campos e dos seus valores, isto é, declarei os campos na ordem Letras e Números e os valores na ordem Números e Letras, o que evidentemente trocou tudo.

$ zenity --forms                           \
    --add-combo Letras --add-combo Números \
    --combo-values "1|2|3|4" --combo-values "A|B|C|D"

Como você pode ver, decididamente não podemos trocar esta ordenação, pois desta forma houve inversão dos campos.

Funcionou inclusive declarando os valores antes de declarar os campos, desde que, obviamente, estejam declarados na mesma ordem.

$ IFS=\| read Let Num <<< "$(zenity --forms            \
      --combo-values 'A|B|C|D' --combo-values '1|2|3|4'\
      --add-combo Letras --add-combo Números)"
$ echo Letra escolhida=$Let
$ echo Número escolhido=$Num
Letra escolhida=B
Número escolhido=2

Ou seja, desde que na ordem correta, é tudo válido, porém não posso dizer o mesmo sobre mais de uma lista embutida em um formulário. A última versão do Zenity neste momento está bugada, pois ao fazermos isso, ganhamos o famigerado segmentation fault, que ocorre quando seu programa invade a área de outro programa ou do sistema operacional.

$ zenity --forms          \
    --add-list Letras --list-values "A|B|C|D" \
    --add-list Números --list-values "1|2|3|4"
Falha de segmentação

Mas creio que isso venha a ser corrigido muito brevemente, pois no help desta versão constam opções que ainda não foram implementadas, como por exemplo a opção --switch, que deveria ocultar os botões <OK> e <CANCELAR> do diálogo --question, mas que quando usada, exibe a mensagem a seguir:

Esta opção não está disponível.
    Use --help para ver todas as opções disponíveis.

Apesar da opção --add-list ainda estar com esse problema, ela permite que se crie uma lista com mais de uma coluna. A quantidade é especificada pelo número de elementos da lista de títulos (cabeçalhos) definidos pela opção --column-values.

Como sempre, vamos ao exemplo:

$ zenity --forms                                   \
    --text "Formulário com lista de duas colunas"  \
    --add-entry "Nome" --add-list="Lista dupla"    \
    --column-values "Núm|Descritivo"               \
    --list-values="1|Primeira Linha|2|Segunda Linha\
|3|Terceira linha|" --show-header

Caso a opção --show-header não tivesse sido usada, os cabeçalhos das colunas não teriam sido exibidos.

Um macete:

Da forma que o formulário foi preenchido e que aparece na imagem, a saída deste diálogo seria:

Jamil Jonas|2Segunda Linha

Repare que no campo da lista, as duas colunas vieram coladas, isto é, a saída foi 2Segunda Linha. Supondo que em ambas as colunas os campos sejam de tamanhos variádos, ficará difícil separar um de outro. Por isso aconselho a usar algo no fim da primeira coluna que sirva como separador. Aconselho o <TAB> que além de ser invisível, é o delimitador default do cut.

Ficaria assim:

$ zenity --forms                                    \
    --text "Formulário com lista de duas colunas"   \
    --add-entry "Nome" --add-list="Lista dupla"     \
    --column-values "Núm|Descritivo"                \
    --list-values="1       |Primeira Linha|2       |\
Segunda Linha|3      |Terceira linha|" --show-header

Sendo que o espaço após cada número da lista foi gerado por um <TAB>.

Fazendo assim, a apresentação do diálogo seria exatamente a mesma, porém a saída seria:

Jamil Jonas|2    Segunda Linha

E agora temos um <TAB> separando os dois campos da lista na saída.

Outro macete:

Para fazer <TAB> em qualquer editor, basta pressionar esta tecla, porém no prompt o <TAB> é quem faz o complemento de palavras (word completion) e portanto não é aceito, ali é necessário fazermos: <CTRL>+V e em seguida <TAB>.



Veja a relação completa dos artigos de Julio Cezar Neves