Tk par l'exemple - le megawidget combobox

 

ulis, 2006-11-09.

Exercices : copiez-collez les exemples, exécutez-les puis modifiez-les. Durée : 60mn.


Objectif

Contrairement à la spinbox qui affiche les valeurs successivement dans sa zone d'affichage, la combobox affiche les valeurs simultanément dans une zone indépendante. (Voir Tk facile - le widget spinbox)

remarque : Il existe plusieurs parfums de combobox.


Conception

Pourquoi se fatiguer quand Tk nous offre tout ce qu'il faut ? En effet, le menubutton permet d'afficher une liste et d'y sélectionner une valeur. La seule doléance c'est que le bouton n'affiche pas la valeur choisie. Il faudra donc y remédier en utilisant son option -textvariable.


Première combobox

  package require Tk

  set ::var orange
  menubutton .b -menu .b.m -textvar ::var -width 10 -relief groove
  menu .b.m -tearoff 0
  foreach value {orange poire pomme banane ananas} \
  { .b.m add command -label $value -command [list set ::var $value ] }
  grid .b

Le widget menubutton crée un bouton auquel on peut attacher un menu. Pour plus de détail voir Tk par l'exemple - le widget menu.

La variable globale ::var contient le texte du bouton. Ce texte est modifié à chaque fois que l'on sélectionne un item du menu.

Cette combobox est fonctionnelle mais pas pas conventionnelle : l'affichage se fait habituellement dans un widget qui ressemble à un widget entry et un mini bouton permet d'ouvrir le menu.


Mini bouton

Pour faire joli il vaut mieux utiliser une image pour le bouton.

La commande image photo permet de donner directement les pixels de l'image dans le script. Il faut préciser les pixels transparents au moyen de l'opération transparency.

  set pixels \
  {
    {#888 #888 #888 #888 #888 #888}
    {#000 #888 #888 #888 #888 #000}
    {#000 #000 #888 #888 #000 #000}
    {#000 #000 #888 #000 #000 #000}
  }
  set img [image create photo]
  $img put $pixels
  for {set i 0} {$i < 4} {incr i} \
  {
    for {set j 0} {$j < 6} {incr j} \
    {
      if {[lindex $pixels $i $j] == "#000"} \
      { $img transparency set $j $i 1 }
    }
  }
  button .b -image $img
  grid .b

Tant de lignes pour un si petit bouton ! Une fois encore on vérifie que plus c'est petit et plus ça prend de place.

La variable pixels contient les pixels de l'image groupés par rangées horizontales. Les pixels de couleur #x000 sont les pixels qui seront transformés en pixels transparents.

L'opération put met les pixels dans l'image.

L'opération transparency permet de rendre transparents certains pixels.

Pour donner la même hauteur au widget d'affichage et au bouton il vaut mieux les mettre dans un widget frame. Cela permettra aussi de donner un cadre commun aux deux widgets internes.


Deuxième combobox

  set pixels \
  {
    {#888 #888 #888 #888 #888 #888}
    {#000 #888 #888 #888 #888 #000}
    {#000 #000 #888 #888 #000 #000}
    {#000 #000 #888 #000 #000 #000}
  }
  set img [image create photo]
  $img put $pixels
  for {set i 0} {$i < 4} {incr i} \
  {
    for {set j 0} {$j < 6} {incr j} \
    {
      if {[lindex $pixels $i $j] == "#000"} \
      { $img transparency set $j $i 1 }
    }
  }
  frame .cb -bd 1 -relief groove
  label .cb.l -textvar ::var -width 10 -bd 0 -bg white
  button .cb.b -image $img -command {post .cb} -bd 1 -relief ridge
  menu .cb.m -tearoff 0
  foreach value {orange poire pomme banane ananas} \
  { .cb.m add command -label $value -command [list set ::var $value ] }
  grid .cb.l .cb.b -sticky nsew
  grid columnconfigure .cb 0 -weight 1

  proc post {w} \
  {
    set m $w.m
    set xm [winfo rootx $w]
    set ym [winfo rooty $w]
    incr ym [winfo height $w]
    $m post $xm $ym
  }

  set ::var orange
  grid .cb

C'est le widget frame contenant qui a le relief.

L'affichage est fait par un widget label qui simule un widget entry en lecture seule. La variable ::var contient la valeur à afficher.

C'est l'option -sticky de la commande grid qui va assurer que le widget button a la même hauteur que le widget label.

L'opération columnconfigure assure, elle, que c'est le widget label qui s'élargira si le widget frame s'élargit.

La procédure post calcule la position du menu. Mais si celui-ci déborde de la fenêtre Tk l'y ramènera automatiquement.

Cet ensemble de widgets qui simulent un widget s'appelle un megawidget.


Les autres parfums

Certaines combobox permettent de taper le début d'une valeur pour que la liste s'y positionne automatiquement.

D'autres permettent de taper n'importe quelle valeur et peuvent même enregistrer les nouvelles valeurs dans la liste.

Plutôt qu'un widget entry les dernières combobox à la mode affiche un bouton qui permet d'exécuter la dernière commande sélectionnée ou une action standard. Par exemple : la flèche de retour arrière de votre navigateur qui revient à la page précédente ou à une des pages affichées dans la liste.


Voir aussi


Discussion


Catégorie Cours | Catégorie Encyclopédie Tk