Audela |
![]() |
Audela permet de reprogrammer entièrement l'interface utilisateur. Cette page donne un exemple qui permet de mettre en oeuvre les fonctions de base à connaître pour générer une interface sous forme d'un script Audela. Il faut évidemment maîtriser le langage Tk pour comprendre le contenu qui suit..

La fenêtre est composée de quatre zones. En partant du bas : une ligne blanche permettant d'entrer des commandes en ligne (interpréteur Tcl). Une zone grise permettant d'afficher des valeurs ou des messages retournés par l'interpréteur Tcl. Une zone de boutons pour effectuer facilement des opérations standard. Une zone noire dans laquelle sera affichée l'image.
La seconde partie, décrite dans la page suivante, consiste à ajouter des fonctionnalités à l'interface simple décrite précédemment (barres de défilement, coordonnées du curseur, valeur du pixel pointé sur l'image, barres de réglages des seuils de visualisation et définir un cadre sur l'image avec la souris):
Nous appellerons le script test.tcl
Avant de commencer à programmer, il est important de savoir comment fonctionne Audela. Le programme audela (audela.exe sous Windows) charge les librairies de Tcl/Tk en premier. Ensuite, il charge les librairies ajoutant les fonctions pour l'astronomie (gestion des images FITS, pilotage de caméra, etc.). Enfin, il interprète le script audela.tcl contenu dans le dossier binwin (ou binlinux sous Linux). Le script
audela.tcl, fourni avec le logiciel, contient un menu permettant de choisir son interface:
La ligne située en bas de l'interface permet de lancer n'importe qu'elle nouvelle interface. Par défaut, c'est le script test.tcl qui sera exécuté par appui sur le bouton "Lancer".La ligne contient deux arguments. Le premier est le chemin d'accès au script et le second argument est le nom du fichier script. De cette façon, il est très simple de changer d'interface.
Notons que l'on peut aussi lancer directement un script d'interface, sans passer par le panneau de choix du script audela.tcl, en ajoutant une option dans la ligne de commande de Audela (cf. raccourci sous Windows):
audela -file ..\test\test.tcl
Le fichier script test.tcl présent dans le dossier test de la distribution du logiciel Audela correspond à l'interface munie des fonctionnalités avancées (barres de défilement, etc.). Pour comprendre comment on construit un tel script, nous allons le décrire étape par étape. Cette page consiste à décrire uniquement les création de l'interface simple sans fonctionnalités avancées. Ces dernières seront décrites à la page suivante.
Nous avons découpé test.tcl en morceaux de façon à bien distinguer les différentes parties du script. Il faut donc coller tous les morceaux bout à bout pour générer test.tcl.
Analysons les premières lignes du script test.tcl :
#--- definition des variables globales (arrays)
global caption
global color
global zone
La première ligne commence par # : c'est un commentaire (inactif). Les trois autres lignes rendent visibles les variables caption, color et zone pour tout le script. Ces variables vont contenir des renseignements généraux à partager entre les différentes fonctions, d'où l'intérêt de les rendre "visible".
#--- description du texte a placer sur l'ecran
set caption(main_title) "test"
set caption(acq) "Acquisition CCD"
set caption(load) "Charger"
set caption(save) "Sauver"
set caption(exit) "Quitter"
set caption(wait) "En cours..."
La variable caption est utilisée ici comme un "array" (tableau) de Tcl. Cela permet de regrouper toutes les légendes dans un seul nom générique (tout comme les structures dans d'autres langages).
#--- definition des couleurs
set color(back) #123456
set color(back_image) #000000
La variable color est aussi un array. La couleur est codée sous la forme de 3 séries de 2 caractères. Chaque série représente une couleur élémentaire pour composition additive. La première série renseigne l'intensité du rouge, la deuxième le vert et la troisième le bleu. Le codage est réalisé en hexadécimal. 00 pour zéro jusqu'à FF pour 256. Par exemple #FF0000 représente le rouge pur le plus intense.
#--- cache la fenetre racine
wm withdraw .
Efface la fenêtre "racine" qui porte le nom point. Il va s'agir en fait de la petite interface contenant le menu de choix d'interface généré par audela.tcl.
#--- cree la fenetre .test de niveau le plus haut
toplevel .test -class Toplevel -bg $color(back)
wm geometry .test 600x400+0+0
wm resizable .test 1 1
wm minsize .test 600 400
wm maxsize .test 1024 768
wm title .test $caption(main_title)
On crée une fenêtre de niveau le plus haut (toplevel) qui s'appele .test dont on spécifie la couleur par la variable color(back).
wm est le Window Manager qui va enregistrer les propriétés de la fenêtre de plus haut niveau.
Le processus de création d'une fenêtre est hiérarchique. Toute fenêtre est obligatoirement la fille d'une autre. La fenêtre principale (root) est toujours désignée par un point. Dans notre exemple .test est une fenêtre fille de . que l'on cache. Seule la fenêtre fille .test reste donc visible à l'écran.
Pour d'avantages de précisions sur la fonction wm, consulter le Guide de référence Tcl/Tk (page 12)
#--- cree la ligne de commande
entry .test.command_line \
-font {{Arial} 8 bold} -textvariable command_line \
-borderwidth 1 -relief groove
pack .test.command_line \
-in .test -fill x -side bottom \
-padx 3 -pady 3
set zone(command_line) .test.command_line
La ligne de commande est un widget (diminutif de WINdow gadGET) de type entry. Les options sont désignées par un mot clé précédé de - et suivi des arguments. Pour d'avantages de précisions sur la fonction entry et ses options, consulter le Guide de référence Tcl/Tk (page 7).
Le widget crée va être affiché à l'écran grâce à la fonction pack. De nombreuses options permettent de placer et de dimensionner le widget à volonté:
L'array zone permet de stocker le nom des fenêtres qui seront utiles pour le programme.
La barre \ située en fin de ligne signifie à l'interpréteur que la ligne suivante contient la suite. Le packer suit la logique de rectangle disponible. Pour une fenêtre donnée, on ne peut packer qu'un widget qui va occuper toute la largeur(-fill x), toute la longueur (-fill y) ou bien les deux (-fill both). Si l'on souhaite ne pas utiliser toute la surface disponible alors il faut emboîter le petit widget dans un plus grand qui sera un widget de type frame par exemple. L'emboîtement logique des widget constitue un point crucial de la création d'une interface à fenêtre sous Tk. Il faut le maîtriser. Pour cela, on consultera le paragraphe "Le packer et sa stratégie" du cours d'Anne Possoz.
#--- cree la console de retour d'etats
listbox .test.lst1 \
-height 3 \
-borderwidth 1 -relief sunken
pack .test.lst1 \
-in .test -fill x -side bottom \
-padx 3 -pady 3
set zone(status_list) .test.lst1
La zone de retour d'états est un widget de type listbox. Pour d'avantages de précisions sur la fonction listbox et ses options, consulter le Guide de référence Tcl/Tk (pages 7, 8).
#--- cree un ascenseur vertical pour la console de retour d'etats
scrollbar .test.lst1.scr1 -orient vertical \
-command {.test.lst1 yview}
pack .test.lst1.scr1 \
-in .test.lst1 -side right -fill y
set zone(status_scrl) .test.lst1.scr1
La barre de défilement est un widget fils de la listbox. Noter que -command contient le nom de la listbox sur laquelle le défilement des barres vertical agit (yview pour vertical). Pour d'avantages de précisions sur la fonction scrollbar et ses options, consulter le Guide de référence Tcl/Tk (pages 10, 11).
Pack remplit toute la hauteur et la barre est collée à droite de la listbox.
Nous allons maintenant disposer les boutons de commande dans une zone de façon à ce qu'ils soient alignés horizontalement. Il faut donc d'abord créer une zone que l'on appelle un frame. Ensuite on peut y insérer les boutons :
#--- cree un frame pour y mettre des boutons
frame .test.frame1 \
-borderwidth 0 -cursor arrow -bg $color(back)
pack .test.frame1 \
-in .test -anchor s -side bottom -expand 0 -fill x
Le widget frame définit une zone d'écran uniforme. Elle permet de rassembler plusieurs autres widgets enfant (ici des boutons). Pour d'avantages de précisions sur la fonction frame et ses options, consulter le Guide de référence Tcl/Tk (pages 9, 10).
#--- cree le bouton 'acquisition'
button .test.frame1.but_acq \
-text $caption(acq) -borderwidth 4 \
-command { testacq }
pack .test.frame1.but_acq \
-in .test.frame1 -side left -anchor w \
-padx 3 -pady 3
set zone(acq) .test.frame1.but_acq
Le bouton acquisition est fils de la frame nommée 'frame1'. L'option command renvoie sur une proc destinée à traiter les actions à effectuer lorsqu'on appuie sur le bouton. Pour d'avantages de précisions sur la fonction button et ses options, consulter le Guide de référence Tcl/Tk (page 9).
L'option -anchor du packer permet d'accrocher le bouton à l'ouest du frame parent.
#--- cree le bouton 'charger'
button .test.frame1.but_load \
-text $caption(load) -borderwidth 4 \
-command { testload }
pack .test.frame1.but_load \
-in .test.frame1 -side left -anchor w \
-padx 3 -pady 3
set zone(load) .test.frame1.but_load
#--- cree le bouton 'sauver'
button .test.frame1.but_save \
-text $caption(save) -borderwidth 4 \
-command { testsave }
pack .test.frame1.but_save \
-in .test.frame1 -side left -anchor w \
-padx 3 -pady 3
set zone(save) .test.frame1.but_save
#--- cree le bouton 'quitter'
button .test.frame1.but_exit \
-text $caption(exit) -borderwidth 4 \
-command { testexit }
pack .test.frame1.but_exit \
-in .test.frame1 -side left -anchor w \
-padx 3 -pady 3
set zone(exit) .test.frame1.but_exit
La zone d'affichage des images est probablement la chose la plus délicate à comprendre dans la création d'une interface. Elle se passe en plusieurs temps. Le premier, décrit maintenant, consiste à créer un widget Tk capable d'accueillir une image. C'est le canvas (canevas en français) :
#--- cree le canevas pour l'image
canvas .test.image1 \
-bg $color(back_image)
pack .test.image1 \
-in .test -expand 1 -side top -anchor center -fill both
set zone(image1) .test.image1
Le widget canvas définit une zone d'écran dans laquelle on pourra ensuite afficher des graphes (l'image dans notre cas). Pour d'avantages de précisions sur la fonction canvas et ses options, consulter le Guide de référence Tcl/Tk (pages 6, 7).
Les liaisons permettent d'associer des commandes à exécuter si un événement a eu lieu (déplacement de la souris, clic, appui sur une touche du clavier, etc.).
#--- detruit la fenetre principale avec la croix en haut a droite
bind .test <Destroy> { destroy .test; exit }
Détruit la fenêtre Toplevel .test si l'on clique sur la croix en haut à droite de la fenêtre.
#--- execute une commande a partir de la ligne de commande
bind $zone(command_line) <Key-Return> {
set resultat [eval $command_line]
if { [string compare $resultat ""] != 0 } {
$zone(status_list) insert end "$resultat"
}
set $command_line ""
}
Si l'on appuie sur la touche Entrée et que le widget $zone(command_line) est actif, alors on exécute les lignes qui suivent. Eval $command_line est le coeur du fonctionnement de la ligne de commande. La fonction eval va interpréter la ligne de commande. La chaîne de caractères, en retour, est placée dans la variable resultat (pas d'accent sur le e en Tcl). Si le résultat n'est pas vide alors il est affiché dans la zone de retour d'état, à la fin de la liste.
Les liaisons (souvent appelées bindings) sont très importantes et permettent de gérer n'importe quel événement de la souris en rapport avec un widget.
On entre ici dans l'utilisation des fonctions que Audela ajoute à Tcl.
#--- declare un buffer pour placer les images en mémoire
buf::create 1
#--- declare une connexion avec une caméra Audine sur LPT1
cam::create audine lpt1 1
#--- declare un nouvel objet de visualisation pour afficher le contenu du buffer
visu::create 1 1
Espace de visu. Permet de créer un lien entre le buffer et la zone image de Tk.
#--- cree un widget image dans un canvas pour afficher l'objet de visualisation
$zone(image1) create image 1 1 -image image1 -anchor nw -tag img1
Crée un widget de type image dans le canvas $zone(image1).
Les boutons sont munis de l'option -command qui exécute des ordres si le bouton est appuyé. Il serait lourd et peu judicieux de placer les ordres à exécuter dans la description du bouton. Pour éclaircir la lecture du script, on préfère que l'option -command entre dans une fonction (proc) spécifique décrite maintenant.
proc testacq { } {
#--- acquisition de l'image
cam1 exptime 15
cam1 bin {2 2}
cam1 acq
vwait status_cam1
#--- statistiques pour calculer les seuils de visu
set mystatistics [buf1 stat]
set mycuts [lrange $mystatistics 0 1]
#--- seuils de visu et affichage
visu1 cut $mycuts
visu1 disp
}
proc testload { } {
global caption
set filename [tk_getOpenFile -title $caption(load) \
-filetypes {{{Images FITS} {.fit}}} \
-initialdir .. ]
if {$filename!=""} {
buf1 load $filename
visu1 disp
}
}
proc testsave { } {
global caption
set filename [tk_getSaveFile -title $caption(load) \
-filetypes {{{Images FITS} {.fit}}} \
-initialdir .. ]
if {$filename!=""} {
buf1 save $filename
}
}
proc testexit { } {
destroy .test
exit
}
Avec cette interface, vous pouvez acquérir, charger, sauver et afficher des images. Vous pouvez maintenant ajouter des fonctions supplémentaires en lisant la page suivante : script7a.htm.