next up previous contents index
Next: Programmation en Perl Up: Programmation en Tcl/Tk Previous: Programmation avec Tcl

   
Programmation avec Tk

Le plus simple est de commencer avec le fameux ``Salut'' :

 

#!/usr/X11R6/bin/wish -f


# Fichier tksalut.
# Affiche le salut et permet de quitter a l'aide d'un boutton.


# On definit 2 "widgets" (boutton, menu, barre d'asenceur...) :
#    .msg est une etiquette ("label") et affiche un message
#    .bye est un boutton auquel est associe une commande si on
#    clique dessus.

label .msg -text "Salut !"
button .bye -text "Bye" -command {exit}


# Maintenant, on place les widgets...

pack .msg .bye

La figure 6.1 montre le résultat de ce script.


  
Figure 6.1: Le fameux Salut avec Tk.
\includegraphics{images/tksalut.eps}

Dans l'exemple qui suit, on peut même saisir un texte et exécuter une commande :

#!/usr/X11R6/bin/wish -f


# Fichier tkedit.
# Saisit du nom d'un fichier et edition de ce fichier.


# 3 widgets : Affichage d'un texte (.l), saisie d'un texte (.e) et
# boutton pour quitter (.bye).

label .l -text "Fichier :"

entry .e -relief sunken -width 30 -textvariable fname

button .bye -text "Bye" -command {exit}


# On place les widgets. L'option "-padx" precise l'espace horizontal
# libre a gauche et a droite du widget, et "-pady" precise l'espace
# vertical libre.

pack .l -side left
pack .e -side left -padx 1m -pady 1m
pack .bye -side left


# En cas de saisie se terminant par "<Control-c>", on quitte le
# script en affichant un message.

bind .e <Control-c> {puts "Merci d'avoir utilise tkedit.\n d'apres
un exemple de \"Le systeme Linux\", par Matt WELSH"; exit }


#  En cas de saisie se terminant par "<Return>", on lance une fenetre
# xterm et on edite le fichier.

bind .e <Return> {
exec xterm -e vi $fname
}

Le script qui suit montre quelque ``ficelles'', comment placer les widgets, gérer les évenements souris ou clavier...La plupart des commandes devraient avoir leur place dans un script Tk digne de ce nom...

#!/usr/X11R6/bin/wish -f


# Fichier tkmin.
# Le minimum que devrait contenir un script digne de ce nom.


# Creation et configuration des widgets.


# Taille du widget "." (fenetre principale).

wm geometry . 600x400

# Creation d'un widget cadre pouvant contenir d'autres widgets.

frame .f

# Creation de deux boutons : 
#    + le premier, contenu dans cadre .f, qui porte le texte "Fichier".
# Ce bouton se voit affecter des couleurs de fond et de devant.
#
#    + le second, .bh, qui porte le texte "Ouvrir un fichier"

button .f.b -text Fichier -fg blue -bg yellow 
button .bh -text "Ouvrir un fichier" 

# On peut configurer le bouton apres sa creation.

.bh config -bg yellow

# Creation d'un widget pouvant saisir du texte.

text .text


# Assignation des evenements claviers ou souris.


# L'exemple qui suit peut servir pour afficher une aide interactive.

# Si le pointeur de la souris arrive sur le widget .f.b ("<Enter>"),
# afficher le bouton .bh ("place").

bind .f.b <Enter> {place .bh -in .f.b -relx 0.5 -rely 1.0}

# Si le pointeur de la souris quitte le widget .f.b ("<Leave>"),
# effacer le bouton .bh ("place forget").

bind .f.b <Leave> {place forget .bh}

# Si on appuie sur <Control-c> dans le widget .text, quitter
# le programme.

bind .text <Control-c> exit

# Association de evenements clavier dans le widget .text.
#    %A designe le caractere imprimable que tape l'utilisateur.
#    { } designe un caractere non imprimable.
#    %W designe le widget recevant la frappe.

bind .text <KeyPress> {
if { "%A" != "{ }" && "%A" != "a"} {%W insert insert %A}
}

# Si on appuie sur le bouton gauche de la souris ("<ButtonPress-1>"),
# et si on le relache ("<ButtonRelease-1>") dans le widget .text.
# Pour le bouton du milieu -2 et celui de droite -3.
#
# %x et %y designent les coordonnees du pointeur de la souris.

bind .text <ButtonPress-1> {puts "pointeur en (%x, %y) sur le widget %W"}
bind .text <ButtonRelease-1> {puts "plus pointeur en (%x, %y) sur le widget
%W"}

# Racourcis : <ButtonPress-1>=<Button-1> et <KeyPress-q>=<q>.

# Le bouton pour quitter.

button .f.q -text Quitter -command {exit} -fg blue -bg yellow


# On place les widgets.


# Affiche contre le cote specifie ("left", "right", "top" ou "bottom").

pack .f.b .f.q -side left

# Si le widget conteneur est plus grand que le widget contenu, il
# peut s'etendre en "both", "none", "x" ou "y".

pack .f -fill x

# Autre facon de placer les widgets : place.
#
# "-relx" et "-rely" precisent la position du widget en fraction
# horizontale et verticale du widget conteneur (entre 0.0 et 1.0).
# "-anchor" precise la position du point d'ancrage de la fenetre.
# Options : "center", "e", "n", "ne", "nw", "s", "se", "sw", "w".
# L'option par defaut est "nw".

place .text -relx 0.5 -rely 0.15 -anchor n

Le script qui suit montre un exemple concret et utile : dessiner des ronds et des rectangles, en utilisant des menus et la souris.

#!/usr/X11R6/bin/wish -f


# Fichier tkdraw.
# Un script qui dessine.


# Initialisation des variables globales servant a stoquer les objets
# et leurs positions.

set oval_count 0
set rect_count 0
set orig_x 0
set orig_y 0


# Definition des fonctions.


# Fonction set_oval : dessine une ovale.

proc set_oval {} {

# Pour que Tcl ne croies pas que ces variables soient locales.

global oval_count orig_x orig_y

# Le . indique la fenetre principale, .c le widgets "canvas" contenu dans
# la fenetre principale. Il y a une hierarchie cf .mbar.file.menu : la
# barre horizontale contient Fichier qui contient un menu
# (voir plus loin).

# Lorque le bouton 1 est appuye, cree une ovale.

bind .c <ButtonPress-1> {

set orig_x %x
set orig_y %y
set oval_count [expr $oval_count + 1]

# -tags sauvegarde cette ovale sous un nom oval1, oval2...

.c create oval %x %y %x %y -tags "oval$oval_count" -fill red
}

# Bouton 1 de la souris + deplacement de la souris : efface l'ovale
# courante et remplace par une nouvelle.

bind .c <B1-Motion> {
.c delete "oval$oval_count"
.c create oval $orig_x $orig_y %x %y  -tags "oval$oval_count" -fill red
}
}
# Fin de la fonction set_oval.

# Fonction set_rect : dessine un rectangle.

proc set_rect {} {

global rect_count orig_x orig_y

bind .c <ButtonPress-1> {

set orig_x %x
set orig_y %y

set rect_count [expr $rect_count + 1]

.c create rectangle %x %y %x %y -tags "rect$rect_count" -fill blue
}

bind .c <B1-Motion> {
.c delete "rect$rect_count"
.c create rectangle $orig_x $orig_y %x %y  -tags "rect$rect_count" -fill
blue
}
}
# Fin de la fonction set_rect.

# Facon plus rapide :
#    set objtype ...
#    .c create $objtype %x %y %x %y -tags "obj$obj_count" -fill blue


# Creation de la barre des menus .mbar.
# -relief cree un sillon autour et -bd specifie l'epaisseur du cadre
# (sillon ici).

frame .mbar -relief groove -bd 3

# Positionnement de .mbar dans la fenetre principale.
# -fill x indique a pack qu'il devra occuper toute la largeur de la
# fenetre qui le contient et -expand qu'il devra grossir pour occuper
# cet espace (cf. page de manuel de pack).

pack .mbar -side top -expand yes -fill x

# Creation des menus Fichier et Objet fils du .mbar.

menubutton .mbar.file -text "Fichier" -menu .mbar.file.menu
menubutton .mbar.obj -text "Objets" -menu .mbar.obj.menu

# Positionnement par rapport au widget pere (ici .mbar).

pack .mbar.file .mbar.obj -side left

# Creation du menu Fichier et ajout de l'item Quitter.

menu .mbar.file.menu
.mbar.file.menu add command -label "Quitter" -command { exit }

# Creation du menu Objet et ajout des items Ovales et Rectangles.

menu .mbar.obj.menu

# Facon plus "classique".

#.mbar.obj.menu add command -label "Ovales" -command { set_oval }

# Avec des boutons coloriees si l'option est validee ou non.

.mbar.obj.menu add radiobutton -label "Ovales" -variable objtype \
    -command { set_oval }

.mbar.obj.menu add radiobutton -label "Rectangles" -variable objtype \
    -command { set_rect }

# Creation du widget canvas .c.

canvas .c
pack .c -side top

# Initialisation des ovales, en invoquant le 1er item du menu Objet.

.mbar.obj.menu invoke 1

Voila, une fois de plus en quelque ligne on a crée un super programme avec une non moins superbe interface graphique (figure 6.2)...


  
Figure 6.2: Un superbe programme Tk en quelque lignes.
\includegraphics[height=7cm, width=9cm]{images/tkdraw.eps}

La plupart des commandes citées on une page de manuel très détaillée avec toutes les options disponibles, bien plus que celles présentées ici...


next up previous contents index
Next: Programmation en Perl Up: Programmation en Tcl/Tk Previous: Programmation avec Tcl
MATHIEU DECORE
1999-11-03
Merci de me dire ce que pensez de ce document.