Changement de langue à la volée

 

Jack.R, 2006-10-21.


Pourquoi

Parce qu'en tant qu'utilisateur, j'apprécie:

Pour ce dernier point, imaginez une interface en chinois dans laquelle vous cherchez désespérément comment basculer en français. C'est tellement plus simple de chercher le mot "Français" que d'essayer de deviner à quoi ressemble ce même mot en chinois!

Parce qu'en tant que programmeur:


Comment

Lorsque j'ai découvert Tcl/Tk, j'ai parcouru beaucoup de page web, fait des recherches et lu des forums sur ce sujet. On en revient presque toujours à l'utilisation de msgcat et à utiliser à chaque fois que c'est possible une option -textvariable plutôt que -text.

Malheureusement, tous les widgets ne disposent pas de l'option -textvariable (exemples les entrées d'un menu, NoteBook des BWidgets, ...). Cela implique d'avoir des façons de faire différentes en fonction du widget utilisé.

Pour remédier à cela, voici une façon de faire. Je dis bien une façon de faire et non la façon de faire. A chacun de trouver celle qui lui convient le mieux. Celle-ci peut certainement être améliorée.

Deux types de textes sont à considérer:

Pour tous les widgets créés au lancement de l'application, on procède par étapes:


Un exemple vaut mieux qu'un long discours

L'ensemble est composé de plusieurs fichiers. En mettre la totalité ici rendrait la page trop longue, ils sont donc téléchargeable:

En voici des extraits correspondants aux étapes pour des boutons:

Extrait, création des boutons sans texte

  proc ::lng::BuildContents {} {
     # Boutons
     set ::lng::Obj(frmButton) [ labelframe .f3 ]
     set ::lng::Obj(btn1) [ button .f3.b1 -command ::lng::Dummy ]
     set ::lng::Obj(btn2) [ button .f3.b2 -command ::lng::Dummy ]
     set ::lng::Obj(btn3) [ button .f3.b3 -command ::lng::Dummy ]
     grid $::lng::Obj(btn1) $::lng::Obj(btn2) $::lng::Obj(btn3)

     grid columnconfigure .f3 0 -weight 1
     grid columnconfigure .f3 1 -weight 1
     grid columnconfigure .f3 2 -weight 1
     pack .f3 -side top -fill x -padx 4 -pady 4 -ipadx 4 -ipady 4
  }

Extrait, mise à jour du texte

  proc ::lng::UpdateContents {} {
     $::lng::Obj(frmButton) configure -text [ mc "msg Buttons" ]
     $::lng::Obj(btn1) configure  -text [ mc "msg Button 1" ]
     $::lng::Obj(btn2) configure  -text [ mc "msg Button 2" ]
     $::lng::Obj(btn3) configure  -text [ mc "msg Button 3" ]
  }

Extrait, changement de langue

  proc ::lng::LoadLanguage {code} {
     if {$code != ""} {
     mclocale $code
     }
     # charge le fichier de langue stocke dans le repertoire msg
     mcload "$::script_home/msg"
  }

  proc ::lng::SwitchLanguage {code} {
     ::lng::LoadLanguage $code
     ::lng::UpdateAll
  }

Discussion dMc : 23/02/07

L'article ci-dessus m'a donné l'idée d'un système permettant a posteriori de msgcatiser un script, l'idéal étant de ne pas modifier le programme originel:

 .top.frame.bouton configure -text [::msgcat::mc "Texte du bouton"]

Hélas! ce qui était un avantage pour l'écriture d'un programme devient un inconvénient ici. Les Widgets lancés par le script (par exemple un tk_messageBox) ne sont pas reconfigurés par le script externe rajouté.

Pour les tk_messageBox, je règle le problème en redéfinissant la commande grace à rename. Je n'ai pas encore fait le tour des commandes à redéfinir.

On trouvera un exemple sur http://danielmacouin.chez-alice.fr/


Catégorie Exemple