Sommaire Carte Index Recherche Nouvelles Archives Liens A propos
[Barre Superieure]
[Barre Inferieure]
[an error occurred while processing this directive]
convert to palmConvert to GutenPalm
or to PalmDoc

[Photo de l'auteur]
par Charles VIDAL

L´auteur:

Président d'un lug gastronomique à Paris. Il aime la philosophie GNU et Open Source, car c'est dans le même ordre d'idée que le partage de connaissances. Il aimerait avoir du temps pour jouer du Saxophone.


Sommaire:

Introduction à Tk

logo de Tcl Tk

Résumé:

Cet article souhaite vous faire appréhender le toolkit graphique de Tcl: Tk. Vous verrez qu'il est facile de faire une interface graphique en quelques lignes. Chose qui depuis les débuts du système X-Window est assez ardue.



 

Tk le Toolkit de Tcl :WISH

Tk a été crée en tant que Toolkit graphique pour le langage Tcl. D'ailleurs on parle souvent de Tcl/Tk; prononcer Tikeulle/Tikais.

C'est un toolkit graphique multi plate-formes qui prend l'apparence du système sur lequel on l'utilise. Il s'associe parfaitement au langage Tcl qui lui aussi est multi plate-formes. Le grand avantage de Tcl et de Tk est leur simplicité. Ce couple permet de faire des applications très rapidement et d'une extrême portabilité. Et tout comme il existe un tclsh pour tcl , il existe un interpréteur Tk et Tcl : wish

 

Bonjour monde !

En introduction, je souhaite vous montrer l'exemple classique montrant la facilité et la simplicité de la mise en oeuvre de Tcl/Tk.
pack [ label .l -text "Bonjour monde" ]

Par rapport à gtk:
#include <gtk/gtk.h>
Int main( int   argc,
          char *argv[] )
{
   /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;

    gtk_init(&&argc, &&argv);
   /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    button = gtk_button_new_with_label ("Bonjour Monde");
    gtk_container_add (GTK_CONTAINER (window), button);
    gtk_widget_show (button);

    /* and the window */
    gtk_widget_show (window);
    gtk_main ();

    return(0);
}
Par rapport à Motif
/* COMPILE  cc xmhello.c -L/usr/X11R6/lib  -lXm -lXt -lX11 -lXmu -o xmhello */

#include <Xm/PushB.h>
#include <Xm/Form.h>

/* Widget */

	Widget      main_widget, pushb;

main(int argc, char **argv)
{
	Widget      form;
	Arg         args[1];
	int         ac = 0;
	XmString    label_str;

	main_widget = XtInitialize(argv[0], "test", NULL, 0, &&argc, argv);
	label_str = XmStringCreate("Bonjour Monde", XmSTRING_DEFAULT_CHARSET);
	XtSetArg(args[ac], XmNlabelString, label_str);
	ac++;
	pushb = XmCreatePushButton(main_widget, "hello", args, ac);
	XtManageChild(pushb);
	XtRealizeWidget(main_widget);
	XtMainLoop();
}
Cependant il est difficile de comparer du source d'un langage de script et d'un langage compilé. Il faut prendre en compte aussi d'autres aspects comme la taille d'exécution en mémoire... Disons que pour faire un coucou au monde, Tk c'est plus simple :). Mais il faudra peut être retenir plus que l'apparence du toolkit ( il est vrai pas trés joli sous X ) le concept, les idées.
Par ailleurs il y a eu des extensions pour modifier l'apparence des Widgets Tk, comme par exemple QTk et TkStep.
Il faut préciser une chose très importante: une interface pour Tk a été réalisée pour la plupart des langages. Et comme beaucoup de langages de script, Tcl-Tk est multi plate-formes.  

Création d'objets graphique Tk

Ce toolkit graphique propose tous les objets graphiques de base pour la construction d'IHM ( Interface Homme Machine ) ; c'est à dire:

Si vous voulez avoir une démo de l'ensemble des widgets disponibles allez voir dans le répertoire /usr/local/lib/tk8.0/demos/ et lancez widget.

L'ensemble de ces objets graphiques reste assez limité . C'est pourquoi plusieurs personnes morales ou physiques ont créé des extensions dont l'une des plus célèbre : Tix les widgets Incr Tcl et récemment les excellents BWidget, l'ensemble des extensions est recensé sur le site de scriptics: Pour plus de détails

 

Hiérarchisation des objets graphiques dans l'interface

Les interfaces graphiques sont créées sur le modèle d'une arborescense de fenêtres ( rectangles ) qui ont leurs propres fonctionnalités.
Les noeuds de l'arborescense sont des conteneurs d'objets graphiques tels que le bouton par exemple. Cette arborescense est décrite en langage Tcl/Tk par Lorsque vous lancez le programme wish, une fenêtre apparaît. C'est celle-ci qui correspond à la racine ..  

Création d'objets graphiques : Le "hello world"

Pour créer n'importe quel objet graphique, la commande Tcl est du type:
nom_objet .(nom_conteneur.)*nom_objet_graphique [propriété valeur]
Exemple: label .monlabel -text "hello world"

Comme vous pouvez le voir cela s'effectue bien en donnant le nom de l'objet graphique à créer , ici un label puis un nom de conteneur , ici . correpondant à la fenêtre principale, puis les propriétés ( -text "hello word" ). on peut signaler que ces arguments peuvent être accédés ou modifiés à tout moment après la création de l'objet graphique.


Et voila votre label a comme texte "Bonjour Monde en français :) "
Vous pouvez l'afficher en exécutant la commande: puts [label .monlabel -text "hello world"] Le label peut être le résultat d'une commande :
.monlabel configure -text " La date [exec date ]"
Pour connaître les options que l'on peut passer à configure pour un widget défini, tapez: ".monlabel configure" sous Wish en mode interactif.
Ceci provoquera une erreur et vous donnera l'ensemble des options que vous pouvez fournir.
 

Les layouts: gestionnaire de disposition de fenêtres .

Vous alliez me dire que rien ne se passe , rien ne s'affiche !?

Effectivement, vous venez de créer un objet de type label, mais vous n'avez pas encore demandé à ce qu'il soit affiché. Car l'affichage de cet objet requiert une information que vous n'avez pas encore précisée. Dans quel layout ( un layout est un gestionnaire de disposition de fenêtres ) vous souhaitez mettre cet objet.

Il existe plusieurs layouts possibles:
  1. Le packer
  2. Le placer
  3. Le grid
Prenons le plus simple : le packer. Il ajoute les objets à l'intérieur de lui-même, suivant les indications de l'utilisateur.Nous y reviendrons plus tard.

Hello Word la totale
label .monlabel -text "hello world" pack .monlabel ou en une ligne pack [label .monlabel -text "hello world"]


Le bouton Voyons maintenant le cas du bouton: button .monboutton -text "hello world" -command "exit" pack .monboutton On remarque que le bouton a une propriété "command" qui prend en argument ( un seul ) la ou les commandes tcl a exécuter lorsque l'utilisateur appuie sur celui-ci. Dans le cas de cet exemple, la commande à exécuter est exit, ce qui aura pour effet de quitter le programme.

 

Association d'objets graphiques aux variables.

La grande puissance du couple Tcl/tk ainsi que sa grande facilité à programmer vient du fait que l'on peut associer à certains objets graphiques une variable correspondant à leur changement d'état. Ainsi nous n'aurons pas besoin d'appeler une fonction pour connaître l'état d'un objet graphique. De même , si l'on change la variable cela influera sur l'objet graphique. Comme vous le voyez ceci facilite grandement la programmation, et permet d'écrire beaucoup moins de code. Exemple

Les boutons à cocher et les boutons radio.

  1. Un bouton à cocher est un bouton à état.
    Ce bouton permet de refléter un état booleen ( pressé ou non ). On peut associer à ce bouton une variable qui par défaut prendra la valeur 0 ou 1. Mais on peut aussi définir la valeur qu'il prendra pour l'état pressé et non pressé.
    Exemple: checkbutton $w.b1 -text "Wipers OK" -variable wipers -relief flat -onvalue "Ok" -offvalue "not Ok"
  2. Un bouton radio est un bouton reflétant l'état d'un ensemble de boutons.
    Les boutons radio sont souvent en groupe , cela permet d'en choisir un parmi plusieurs. Pour les associer il vous suffit d'y associer la même variable et de donner la valeur que prendra cette variable si le bouton radio est selectionné.
    Exemple:
    radiobutton .b1 -text "Premier " -variable size -value 1 radiobutton .b2 -text "Second " -variable size -value 2

La zone de saisie ou "entry" Cet objet graphique offre une zone d'une seule ligne de texte afin que l'utilisateur la renseigne.
Exemple:
entry .e -textvariable toto -width 40  

Les conteneurs ou placeurs

Généralement on place les objets graphiques dans un cadre (frame). Attention, il est déconseillé d'utiliser deux ou trois d'entre eux sur un même cadre. Ils sont au nombre de trois:
  1. Le packer: Il positionne les objets graphiques suivant des orientations:
    1. top
    2. bottom
    3. right
    4. left

    Exemple:
    pack [ button .b1 -text top ] -side top
    pack [ button .b2 -text bottom ] -side bottom
    pack [ button .b3 -text right ] -side right
    pack [ button .b4 -text right ] -side left
    

    On peut aussi configurer les widgets qu'il contient lors d'un agrandissement de fenêtre: option -expand (yes|no) -fill ( x|y| both)

  2. Le placeur: Il permet de placer ( d'où son nom ) un objet graphique à la position x y.

    Exemple: place [ label .l -text "Avec Place"] -x 100 -y 100 .l configure -bg red

  3. La grille Position dans une grille virtuelle ayant des lignes (row) et des colonnes (column) est idéale pour les rolodex, ou les zones de saisies multiples. La syntaxe est la suivante: Créez vos widgets par exemple .e_name puis pour les afficher tapez: label .mainlbl2 -text "Label 2" -bd 2 -relief sunken grid .mainlbl2 -row 0 -column 1 -sticky news label .mainlbl1 -text "Label 1" -bd 2 -relief raised grid .mainlbl1 -row 0 -column 0 -sticky news label .mainlbl3 -text "Label 3" -bd 2 -relief solid grid .mainlbl3 -row 1 -column 0 label .mainlbl4 -text "Label 4" -bd 2 -relief groove grid .mainlbl4 -row 1 -column 1

 

La liste des widgets créés

Nous pouvons obtenir la liste des objets graphiques créés grâce à la commande winfo.

 winfo exists name_object
Nous pouvons également obtenir la liste de tous les widgets créés grâce à la commande:
winfo children .
Cette caractéristique de tcl/tk n'existe pas dans les autres toolkits graphiques compilables ( gtk,awt,motif ...).

 

Les évènements

Tk gére les événements et exécute les commandes lorsque que vous les avez précisées par -command. Mais il y a des cas ou l'on souhaite gérer plus finement les événements, ou gérer plusieurs événements pour un widget , par exemple le canvas.

Lorsque l'on souhaite réagir à un événement on utilise la commande bind bind nomduwidget nom de l'événement code tcl.
 

Un petit exemple

Nous allons créer une interface pour voir le contenu des fichiers tar.
L'interface est constituée d'une liste et de deux scrollbars permettant de déplacer l'affichage de la liste en X et en Y.
Pour réaliser ceci voici en quelques mots la structure du script tcl:
  1. On construit l'interface ( proc makegui ).
  2. On insère l'ensemble des chemins des widgets dans un tableau tabgui.
  3. On regarde le nombre d'arguments passés au programme, s'il est égal à zéro alors on sort.
  4. On ouvre un descripteur de fichier vers un tube avec le programme tar -tzvf nom_du_fichier_tar
  5. On insère chaque ligne lue sur le tube dans la liste.
On capte l'évènement clavier "Control C" pour quitter l'application:
bind all <Control-c> {destroy .}

Bon, c'est juste un petit exemple, que l'on peut améliorer par la suite. On peut tester si le fichier tar est compressé ou non avec la commande string fist de tcl. Et aussi si on n'a pas entré d'argument, on peut alors proposer à l'utilisateur une boîte de dialogue de sélection de fichier. Par la suite, on peut élaborer d'avantage l'interface en créant un popmenu, permettant d'agir sur les fichiers dans l'archive tar. Et pour finir, on peut réaliser une barre de menu en haut, permettant d'ouvrir un nouveau fichier, de créer une nouvelle archive etc...
#!/bin/sh
# the next line restarts using wish \
exec wish8.0 "$0" "$@"

global tabgui

proc makegui { } {
global tabgui
#
# Creation des scrollbars pour la liste
# puis on position la scrollbar horizontale à droite , remplissant horizontalement la fenetre
# et on position la scrollbar verticale en bas , remplissant verticalement la fenetre
#
set tabgui(scrollv) [scrollbar .scrollv -command ".list yview"]
pack $tabgui(scrollv) -side right -fill y
set tabgui(scrollh) [scrollbar .scrollh -command ".list xview" -orient horizontal ]
pack $tabgui(scrollh) -side bottom -fill x
#
# Creation de la liste en l'associant à la scrollbar
#
#
set tabgui(list) [listbox .list  \
                -yscroll "$tabgui(scrollv) set" \
                -xscroll "$tabgui(scrollh) set" \
                -relief sunken -width 20 -height 20 \
        -setgrid yes ]
pack $tabgui(list) -side left -fill both -expand yes
wm minsize . 1 1
}

#
# Creation de l'IHM
#
makegui

if $argc>0 {set tarfile [lindex $argv 0]} else {puts stderr "fichier tar manquant" ; exit}
set command "tar -tzvf $tarfile"
set tube [ open |$command r]
 while {![eof $tube]} {
    set tarresult  [ gets $tube ]
    $tabgui(list)  insert end $tarresult
}

bind all <Control-c> {destroy .}
 

Ressources

 

Discussion sur cet article

Chaque article possède sa page de discussion. Vous pouvez y soumettre un commentaire ou lire ceux d´autres lecteurs:
 page de discussion 

Site Web maintenu par l´équipe d´édition LinuxFocus
© Charles VIDAL, FDL
LinuxFocus.org

Cliquez ici pour signaler une erreur ou envoyer un commentaire à Linuxfocus

2001-03-18, generated by lfparser version 2.8