IV. Cases à cocher et boutons radio▲
Ce chapitre traite des widgets cases à cocher (checkbutton) et des boutons radio (radiobutton). Bien qu'ils se ressemblent beaucoup, on les utilise dans des buts différents.
Les cases à cocher servent à sélectionner autant d'éléments que nécessaire, comme on le fait, par exemple, avec une liste de courses. Les boutons radio servent dans des situations où l'on doit faire un choix dans un groupe d'éléments, comme dans le cas d'un examen de type QCM (questionnaire à choix multiples) :
Q1 : En quelle année Christophe Colomb a-t-il découvert l'Amérique ?
A) 1400
B) 1470
C) 1472
D) 1492
E) Aucune des dates précédentes
Comme les boutons radio sont regroupés, on ne peut sélectionner qu'un et un seul bouton par groupe. Si le choix par défaut est toujours A, et que l'on clique sur D, A sera automatiquement désélectionné.
Les deux sections de ce chapitre traitent de l'utilisation de ces deux types de widgets et de la façon de les configurer.
IV-A. Le widget Checkbutton▲
Au chapitre 3, Le bouton de base, nous avons vu les options associées au widget bouton. Une case à cocher est considérée comme un bouton particulier (et elle utilise quasiment les mêmes options), bien que la façon dont elle est utilisée dans une application diffère de celle d'un bouton standard.
Au lieu de cliquer sur une case à cocher pour que quelque chose se passe immédiatement, on l'utilise pour indiquer une réponse de type « oui/non » : si la case est cochée, cela signifie « oui », si elle n'est pas cochée, cela signifie « non ». On pourrait, par exemple, utiliser des cases à cocher pour énumérer les options d'impression d'un document : les textes de ces cases pourraient être « Imprimer un en-tête de page », « Pages paires uniquement », « Pages impaires uniquement » et « Numérotation des pages ». Le bas de la fenêtre ne contiendrait qu'un bouton « Imprimer » et, lorsque l'on cliquerait dessus, le programme rechercherait les cases cochées et soumettrait la demande d'impression avec les options choisies.
On peut utiliser des cases à cocher pour des fenêtres énumérant plusieurs travaux à exécuter (c'est le cas des gestionnaires de traitement par lot) afin de demander à l'utilisateur quelles sont les tâches concernées. Si la case placée à côté de la tâche est cochée, celle-ci sera lancée, sinon elle ne sera pas prise en compte.
À chaque fois qu'une case à cocher est utilisée, l'application demande à l'utilisateur de répondre à une question de type « oui/non ». Les cases formant un groupe ont, typiquement, un rapport les unes avec les autres (comme dans l'exemple d'impression d'un document), mais cela n'est pas obligatoire, car la réponse à chaque case est indépendante de tous les autres widgets ou cases à cocher de l'écran.
Une case à cocher ressemble à un bouton ; elle affiche une chaîne de texte, mais possède aussi un indicateur dans sa partie gauche. Par défaut, les bords extérieurs de la case ne sont pas en relief comme ceux d'un bouton standard, mais l'indicateur (le petit carré à gauche) apparaît, lui, en trois dimensions.
Une case à cocher fonctionne de la même façon qu'un bouton de base : on clique dessus avec le bouton gauche de la souris. Un bouton changera la valeur de son option -relief (la façon dont ses bords sont tracés) afin de faire comme s'il avait été enfoncé, tandis qu'une case à cocher ne modifiera que l'état de son indicateur. Si la case est cochée, l'indicateur sera représenté comme s'il avait été enfoncé dans la fenêtre et rempli d'une couleur plus sombre(20).
La terminologie est parfois confuse entre l'état (ou la valeur) de l'indicateur et l'état de la case elle-même. Si l'indicateur ressemble à un petit bouton surélevé sans couleur, la case n'est pas cochée (case de gauche de la figure 4.1). S'il est coloré, elle est cochée (case de droite de la figure 4.1). L'état de la case complète (dont l'indicateur) peut être normal, actif ou désactivé. Les deux cases de la figure 4.1 sont dans l'état normal.
Comme pour toute création de widgets, une case à cocher est créée en utilisant une méthode portant le nom du widget avec sa première lettre en majuscule, Checkbutton, et appelée par le widget parent. L'utilisation classique en est :
$cc
=
$widget_parent-
>
Checkbutton( [ option =>
valeur, . . . ] )->
pack
;
En plus de posséder un indicateur avec un état, une case à cocher a aussi une fonction de rappel associée à son option -command. Cette fonction est appelée lorsque la case est cochée (quel que soit l'état de l'indicateur). Cependant, il n'est pas toujours nécessaire d'associer une fonction de rappel aux boutons radio et aux cases à cocher, car on peut vérifier leur état plus tard dans le programme.
L'état booléen d'une case à cocher est stocké dans une variable que l'on indique via l'option -variable à la création de la case. Chaque case à cocher doit utiliser sa propre variable pour stocker son propre état et, lorsqu'elle est cochée, cet état est mis à jour. Les options pouvant modifier le comportement d'une case à cocher sont énumérées ci-dessous et expliquées en détail plus loin.
IV-A-1. Options des cases à cocher ▲
Les options suivantes fonctionnent exactement comme celles des boutons de base, je ne les détaillerai donc pas. Reportez-vous au chapitre 3, Le bouton de base, pour la description complète des options suivantes : -activebackground, -activeforeground, -anchor, -background, -borderwidth, -cursor, -disabledforeground, -font, -foreground, -height, -highlightbackground,-highlightcolor,-highlightthickness, -justify, -padx, -pady, -state, -takefocus, -text, -textvariable, -underline, -width, et -wraplength.
Les autres options se comportent un peu différemment, ou n'existent que pour le widget Checkbutton. Elles sont décrites dans la liste suivante. Certaines options (comme -selectimage) ne concernent que l'indicateur. Rappelez-vous que l'option -state concerne le widget dans son ensemble, et que l'état de l'indicateur est géré par les options -onvalue, -offvalue, -indicatoron et -variable.
-activebackground => couleur
- Configure la couleur que devra prendre le fond du widget lorsque le curseur de la souris est au-dessus de lui.
-activeforeground => couleur
- Configure la couleur que devra prendre le texte lorsque le curseur de la souris sera au-dessus du widget.
-anchor => 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' |'nw' | 'center'
- Permet de positionner le texte à la position spécifiée dans le widget. Plus le widget est grand, plus cet effet est notable.
-background => couleur
- Configure la couleur de fond du widget (derrière le texte).
-bitmap => nom_bitmap
- Affiche nom_bitmap à la place du texte.
-borderwidth => montant
- Change la largeur du bord tracé autour du widget. Modifie aussi la largeur de l'indicateur. La valeur par défaut est 2.
-command => fct_rappel
- Associe une fonction au bouton, qui sera appelée lorsque le bouton sera pressé.
-cursor => nom_curseur
- Indique que le curseur de la souris se changera en nom_curseur lorsqu'il sera au-dessus du widget.
-disabledforeground => couleur
- Configure la couleur que devra prendre le texte lorsque -state sera 'disabled'.
-font => nom_fonte
- Change la fonte du texte du widget.
-foreground => couleur
- Change la couleur du texte en couleur.
-height => montant
- Configure la hauteur du bouton : montant est exprimé en distances d'écran.
-highlightbackground => couleur
- Configure la couleur du rectangle de focus autour du widget lorsque celui-ci n'a pas le focus.
-highlightcolor => couleur
- Configure la couleur du rectangle de focus autour du widget lorsque celui-ci a le focus.
-highlightthickness => montant
- Configure l'épaisseur du rectangle de focus.
-image => ptr_image
- Affiche l'image ptr_image à la place du texte.
-indicatoron => 0 | 1
- Précise s'il faut afficher l'indicateur.
-justify => 'left' | 'right' | 'center'
- Indique le bord du widget contre lequel s'alignera le texte.
-offvalue => valeur
- Donne la valeur utilisée lorsque la case n'est pas cochée. Par défaut, la valeur, qui doit être un scalaire, est 0.
-onvalue => valeur
- Donne la valeur utilisée lorsque la case est cochée. Par défaut, la valeur, qui doit être un scalaire, est 1.
-padx => montant
- Précise l'espace à laisser entre le texte/indicateur et les bords gauche/droit du widget.
-pady => montant
- Précise l'espace à laisser entre le texte/indicateur et les bords haut/bas du widget.
-relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken' | 'solid'
- Modifie le type du contour tracé autour du widget.
-selectcolor => couleur
- Indique la couleur de l'indicateur lorsqu'il est coché.
-selectimage => ptr_image
- Indique l'image à afficher à la place du texte lorsque la case est cochée. Cette option est ignorée si -image n'est pas utilisée.
-state => 'normal' | 'disabled' | 'active'
- Indique l'état de réactivité du widget. Si cette option vaut "disabled", il ne répondra jamais.
-takefocus => 0 | 1 | undef
- Indique si le widget peut ou non prendre le focus.
-text => texte
- Indique le texte affiché dans le widget.
-textvariable => \$variable
- Pointeur vers une variable contenant le texte à afficher dans le widget.
-underline => n
- Souligne le nième caractère du texte.
-variable => \$valeur
- Affecte la valeur coché/non coché de l'indicateur à
$valeur
.
-width => montant
- Configure la largeur du widget. montant est exprimé en distances d'écran.
-wraplength => montant
- Indique que le texte passera à la ligne lorsqu'il dépassera ce montant.
IV-A-2. Stockage de l'état de l'indicateur ▲
L'option -variable associe une variable à l'état de l'indicateur en passant une référence comme valeur. Pour utiliser le scalaire $valeur
, il faut ajouter le code suivant à la liste des options de l'appel à la méthode Checkbutton :
-
variable =>
\$valeur
Tout comme l'option -textvariable indique la variable associée au texte de la case à cocher, cette option indique la variable associée à l'indicateur. Lorsque la case sera cochée, $valeur
contiendra l'état de l'indicateur (la valeur placée dans $valeur est définie par -onvalue et -offvalue, et vaut 1 et 0, respectivement).
En plus d'utiliser la souris pour modifier l'état de l'indicateur, vous pouvez également modifier directement $valeur
. Si votre code contient $valeur
=
1
à un endroit donné, l'indicateur sera coché. Vous pouvez écrire $valeur
=
1
avant de créer la case à cocher afin de cocher l'indicateur de celle-ci lors de sa création. Si vous changez la valeur de $valeur après la création de la case, celle-ci se modifiera pour refléter cette nouvelle valeur. La fonction associée à -command (s'il y en a une) n'est pas appelée lorsque la valeur de $valeur
est modifiée.
L'utilisation de -variable est habituellement la façon la plus simple de positionner l'état de l'indicateur de la case. Voici un exemple comportant deux boutons permettant de changer la valeur contenue dans $cc_valeur
:
$cc_valeur
=
0
;
$cc
=
$mw-
>
Checkbutton(
-
text =>
"Case à cocher"
,
-
variable =>
\$cc_valeur
,
-
command =>
sub {
print
"Cochée !
$cc_valeur\n
"
}
)->
pack
( -
side =>
'top'
);
$mw-
>
Button(
-
text =>
"Case cochée"
,
-
command =>
sub {
$cc_valeur
=
1
}
)->
pack
( -
side =>
'left'
);
$mw-
>
Button(
-
text =>
"Case non cochée"
,
-
command =>
sub {
$cc_valeur
=
0
}
)->
pack
( -
side =>
'left'
);
La figure 4.2 montre le résultat obtenu :
La valeur stockée dans $cc_valeur
peut être modifiée de trois façons différentes : en cliquant sur la case à cocher, en cliquant sur le bouton « Case non cochée », ou en cliquant sur le bouton « Case cochée ». Vous ne verrez s'afficher « Cochée ! » dans la fenêtre de terminal à partir de laquelle vous avez lancé le script que si vous cliquez sur la case à cocher. Il existe d'autres façons de changer la valeur associée à une case : étudiez les méthodes invoke, select, deselect et toggle plus loin dans ce chapitre.
IV-A-3. Affectation d'une fonction de rappel ▲
L'option -command fonctionne exactement comme elle le fait avec un bouton standard. Cependant, la fonction de rappel associée à une case à cocher réalise, habituellement, des tâches moins évidentes. Souvent, il n'y a pas de fonction associée à une case à cocher, car l'information importante est l'état de cette case, plutôt que la détection du cochage de celle-ci.
L'une des choses que peut faire une case à cocher est de modifier l'apparence de la fenêtre. Une telle case pourrait être celle de la figure 4.3.
Lorsque l'utilisateur coche la case, la fenêtre se transforme comme par magie pour ressembler à celle de la figure 4.4.
Voici le code qui réalise ce tour de magie :
#!/usr/bin/perl -w
use Tk;
my $mw
=
MainWindow->
new;
$mw
=
MainWindow->
new;
$mw-
>
title("Case à cocher"
);
## On crée les autres widgets, mais on ne les place pas encore !
for ( $i
=
1
; $i
<=
5
; $i
++
) {
push
( @boutons
, $mw-
>
Button( -
text =>
"Bouton
$i
"
) );
}
$mw-
>
Checkbutton(
-
text =>
"Affiche tous les widgets"
,
-
variable =>
\$cc_valeur
,
-
command =>
sub {
if ($cc_valeur
) {
foreach (@boutons
) {
$_
->
pack
( -
side =>
'left'
);
}
}
else {
foreach (@boutons
) {
$_
->
pack
('forget'
);
}
}
}
)->
pack
( -
side =>
'top'
);
MainLoop;
Pour pouvoir afficher des widgets plus tard dans le programme, on les crée d'abord et on stocke leurs références dans le tableau @boutons
. Les boutons de cet exemple ne sont pas très utiles, car ils n'ont même pas de -command associée. Normalement, ils devraient avoir chacun une tâche spécifique à réaliser lorsqu'ils sont cliqués ; dans notre exemple, nous voulons simplement qu'ils existent.
Puis, nous créons notre case à cocher magique. Lorsque cette case est cochée (quel que soit l'état de son indicateur), elle appelle la fonction pointée par -command. Cette fonction examine la valeur courante de $cc_valeur
, affiche les boutons si la case est cochée et les cache si elle ne l'est pas. La valeur de $cc_valeur
est modifiée avant que cette fonction ne soit appelée. Lorsque la case est à nouveau cochée, les autres boutons seront supprimés de la fenêtre et celle-ci se réduira pour retrouver la taille qu'elle avait précédemment.
Ce type de configuration est très pratique lorsque l'on souhaite conserver une fenêtre de base tout en gardant la possibilité d'afficher des widgets supplémentaires si l'utilisateur désire utiliser les fonctions avancées proposées par ceux-ci. On peut, par exemple, créer une fenêtre de recherche disposant d'un emplacement pour entrer du texte, d'un bouton pour lancer la recherche et d'une case à cocher pour les recherches plus élaborées. Cocher cette case ajoutera d'autres widgets en bas de la fenêtre afin de permettre de traiter les différences entre majuscules et minuscules, les expressions rationnelles, et d'utiliser d'autres mécanismes de recherche plus élaborés.
IV-A-4. Valeurs de cochage▲
Si vous n'aimez la valeur de cochage par défaut, 1, vous pouvez utiliser l'option -onvalue pour la modifier :
-
onvalue =>
valeur ## la valeur par défaut est 1
Même chose pour la valeur associée à une case non cochée :
-
offvalue =>
valeur ## la valeur par défaut est 0
Ces options changeront les valeurs stockées dans $variable
. Selon la façon dont vous voulez que la case à cocher interagisse avec le reste de votre application, il est parfois préférable d'utiliser des valeurs différentes. La nouvelle valeur peut être n'importe quoi, pourvu que ce soit une valeur scalaire : cela signifie que l'on peut utiliser des références à des tableaux et à des hachages, si nécessaire.
Il est préférable de conserver l'opposition des significations de -onvalue et -offvalue. Si -onvalue contient, à un instant donné, la chaîne « ON », -offvalue devrait logiquement valoir « OFF ». Bien sûr, si le but de cette case à cocher est d'utiliser une valeur plus précise de Π , -onvalue pourrait contenir « 3.14159265359 », et -offvalue « 3.14 ».
Prenez garde à l'utilisation de valeurs inhabituelles pour -onvalue et -offvalue. Si vous configurez -variable avec quelque chose qui n'est égal ni à l'une ni à l'autre, la case sera considérée comme non cochée, même si la valeur associée à -variable est différente de celle associée à -offvalue. Si, par exemple, on utilise la configuration -
onvalue =>
1
, -
offvalue =>
0
, -
variable =>
\$variable
, avec $variable
valant 3, la case sera considérée comme non cochée.
IV-A-5. Couleur de l'indicateur ▲
L'option -selectcolor permet de modifier la couleur que prend l'indicateur lorsque la case est cochée :
-
selectcolor =>
couleur
La valeur par défaut est "#b03060" (rose foncé). La modification de cette valeur changera aussi la couleur du fond de la case lorsqu'elle est cochée et que l'option -indicatoron vaut 0.
IV-A-6. Masquage de l'indicateur ▲
L'un des signes distinctifs entre une case à cocher et un bouton standard est la présence d'un indicateur. On utilise l'option -indicatoron pour demander à Perl/Tk de ne pas tracer cet amusant petit carré :
- -indicatoron => 0 | 1
Ainsi que nous l'avons vu dans les exemples précédents, la valeur par défaut associée à -indicatoron est 1 (afficher l'indicateur). Si l'on remplace cette valeur par 0, la case à cocher ressemblera presque à un bouton normal (sans autant d'espace autour du texte). Malgré cette ressemblance, son comportement lors d'un clic (pour cocher l'indicateur, qui est caché) est entièrement différent (voir la figure 4.5). Notez que l'option -relief est complètement ignorée lorsque -indicatoron est positionnée à 0.
Dans cet exemple, la couleur du fond de la case cochée est celle de -selectcolor, pas de -backgroundcolor. On peut utiliser une configuration sans indicateur si l'on change le texte de la case afin de refléter son nouvel état. Par exemple, lorsque l'on passe de « Connexion autorisée » à « Connexion non autorisée ».
IV-A-7. Affichage d'une image à la place du texte ▲
Comme avec un bouton normal, on peut utiliser l'option -image afin de remplacer le texte d'une case à cocher par une image. Une autre option, -selectimage, permet d'afficher une image différente lorsque la case a été cochée :
-
image =>
$ptr_img1
[ , -
selectimage =>
$ptr_img2
]
L'option -selectimage est tributaire de l'utilisation de -image, d'où la notation utilisée dans cette ligne.
Les $ptr_img
peuvent être créés en utilisant les mêmes méthodes que celles utilisées au chapitre 3 avec l'option -image :
$fleche
=
$mw-
>
Photo(-
file =>
"nextart.gif"
);
L'image sera mise sur la case à la place du texte. Ces options ont priorité sur -text ; si -text et -image sont utilisées, -text sera ignorée.
L'image affichée dépend du fait que la case soit cochée ou non. Si seule l'option -image est spécifiée, cette image sera affichée quel que soit l'état de la case. Si -selectimage est aussi spécifiée, l'image qui lui est associée s'affichera lorsque la cache est cochée. La figure 4.6 montre un exemple utilisant les deux options, dont les cases à cocher ont été créées avec le code suivant :
$img1
=
$mw-
>
Bitmap( -
file =>
"/usr/X11R6/include/X11/bitmaps/woman"
);
$img2
=
$mw-
>
Bitmap( -
file =>
"/usr/X11R6/include/X11/bitmaps/xlogo32"
);
$mw-
>
Button(
-
text =>
"Fin"
,
-
command =>
sub {
exit }
)->
pack
( -
side =>
'bottom'
);
$mw-
>
Checkbutton(
-
text =>
"Case à cocher"
,
-
image =>
$img1
,
-
selectimage =>
$img2
,
-
variable =>
\$cc_valeur
)->
pack
( -
side =>
'top'
);
L'utilisation de deux images différentes pour indiquer qu'une case est cochée ou non a sûrement plus de sens si l'on configure aussi l'option -indicatoron à 0. On peut, par exemple, vouloir indiquer qu'un document est verrouillé (en lecture seule) ou déverrouillé en utilisant l'image d'un cadenas fermé pour -image et d'un cadenas ouvert pour -selectimage.
Pour l'exemple précédent, j'ai choisi d'utiliser des fichiers bitmap comme images. Au lieu d'utiliser l'option -image pour afficher un bitmap, on peut utiliser directement l'option -bitmap. Celle-ci est rigoureusement la même que celle du bouton standard ; elle remplace le texte de la case par le bitmap spécifié (voir la figure 4.7).
À la différence des options -image et -selectimage, l'utilisation de -bitmap ne modifiera pas l'image lorsque la case sera cochée ou décochée.
On pourrait penser que l'utilisation d'images à la place de textes rend une application plus facile à comprendre pour les utilisateurs ne parlant pas notre langue. Cependant, si l'on utilise trop de cases avec des images, on peut arriver à rendre les choses plus confuses encore pour les utilisateurs. Quelques icônes aisément compréhensibles sont préférables à un ensemble important d'icônes peu parlantes.
IV-A-8. Style d'une case à cocher ▲
Bien qu'un bouton et une case à cocher partagent tous deux les options -relief et -borderwidth, et qu'elles signifient exactement la même chose pour ces deux types de widget, leurs effets diffèrent lorsqu'elles sont utilisées avec une case à cocher : cela à cause de l'indicateur. Rappelons les valeurs possibles de ces deux options :
- -relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken' | 'solid'
- -borderwidth => montant
La figure 4.8 montre les différents types de contours lorsque l'on utilise la valeur par défaut de -borderwidth. La valeur par défaut de -relief est 'flat', car le contour extérieur d'une case à cocher n'est pas modifié lorsque l'on clique sur la case ; seul l'indicateur change. La figure 4.8 montre aussi que les bords de la case à cocher sont beaucoup plus près du texte ; les valeurs par défaut de -padx et -pady sont inférieures à celles d'un bouton. L'option -relief n'affecte pas l'indicateur.
L'option -borderwidth affecte à la fois le contour de la case et l'indicateur se trouvant dans celle-ci. L'indicateur lui-même reste de la même taille, quelle que soit la valeur de -borderwidth de la case, mais ses bords changent d'épaisseur. Lorsque l'on utilise une grande valeur, on obtient des résultats intéressants, montrés par la figure 4.9.
Nous avons utilisé une valeur de 4 pour -borderwidth, et l'on peut constater que les contours sont devenus un peu plus épais, de même pour les bords de l'indicateur. Avec une valeur plus importante de -borderwidth, il y a beaucoup moins de place pour afficher la couleur de l'indicateur lorsqu'il est coché : voyez-vous le minuscule carré, au milieu de ces indicateurs ?
Dans la figure 4.10, -borderwidth vaut 10. Remarquez la différence ! On ne peut plus voir du tout l'indicateur, bien qu'il y ait encore suffisamment de place pour lui. Que ces cases soient cochées ou non, il n'y a aucun moyen de connaître leur état courant, car l'indicateur est invisible.
Je recommande fortement de ne pas utiliser l'option -borderwidth avec une case à cocher à cause de cet effet de bord.
IV-A-9. Configuration d'une case à cocher ▲
Comme le widget bouton, une case à cocher dispose de méthodes permettant de la manipuler après sa création. Celles-ci peuvent être appelées à tout moment après la création de la case à cocher, même avant qu'elle ne soit affichée à l'écran.
Les méthodes configure et cget peuvent également être utilisées, elles sont décrites à l'annexe A, Configuration des widgets avec configure et cget.
IV-A-10. Cocher ou décocher une case ▲
On peut forcer une case à passer de l'état coché à l'état non coché, et vice versa, à l'aide des méthodes deselect et select.
La méthode deselect positionnera toujours l'indicateur comme étant non coché et la variable assignée par l'option -variable recevra la valeur de l'option -offvalue :
$cc-
>
deselect();
L'opposé de deselect, select, forcera l'indicateur dans l'état coché et la variable assignée par -variable à la valeur de -onvalue :
$cc-
>
select
();
Ces deux méthodes sont ignorées si l'option -state vaut 'disabled'.
On peut aussi commuter l'indicateur d'un état à l'autre à l'aide de la méthode toggle :
$cc-
>
toggle();
L'appel de toggle ne provoque pas celui de la fonction de rappel associée à l'option -command.
IV-A-11. Clignotement d'une case à cocher ▲
On peut faire clignoter l'indicateur en utilisant la méthode flash. Les couleurs basculeront entre la couleur définie par -background et celle définie par -foreground :
$cc-
>
flash();
IV-A-12. Invocation d'une case à cocher ▲
Pour réaliser la même action qu'en cochant la case avec le bouton gauche de la souris, il suffit d'appeler la méthode invoke :
$cc-
>
invoke();
Cela forcera l'appel de la fonction de rappel associée à -command ; cela passera aussi l'indicateur d'un état à l'autre.
IV-B. Le widget Radiobutton▲
Un bouton radio ressemble à une case à cocher, car il contient aussi un indicateur sur son côté gauche. Cet indicateur est un losange plutôt qu'un carré : comme avec une case à cocher, il est en 3D et apparaît légèrement surélevé lorsque le bouton n'est pas sélectionné.
La différence principale entre un bouton radio et une case à cocher concerne les rôles qu'ils jouent dans une application. Un bouton radio sert à sélectionner un choix parmi plusieurs possibilités :
- dans un questionnaire à choix multiples, les réponses A, B, C, D ou E ;
- la version d'un utilitaire que vous souhaitez utiliser ;
- le montant de vos revenus annuels : 0-120 000, 120 001-180 000, 180 001-240 000, 240 001 et plus ;
- votre type de nourriture préférée : bœuf, poulet, ou végétarienne.
Dans chaque exemple, une seule réponse convient. Cela n'aurait aucun sens, par exemple, d'avoir à la fois un salaire de 100 000 et de 200 000 francs. Lorsque vous répondez à un questionnaire à choix multiples, vous ne pouvez pas choisir toutes les réponses et espérer que le correcteur vous suive : vous ne devez en choisir qu'une.
Comme les boutons radio servent à faire un choix parmi plusieurs, il faut toujours en créer au moins deux(21). Cela n'aurait aucun sens de poser une question s'il n'y avait qu'une réponse possible. Les boutons radio sont toujours créés par groupes de deux ou plus.
IV-B-1. Création de boutons radio ▲
Jusqu'à maintenant, nous avons appris à ne créer qu'un seul widget à la fois. Comme les boutons radio font toujours partie d'un groupe, on a généralement besoin d'en créer plusieurs en même temps. On peut donc être plus efficace et créer tous les widgets aussi rapidement et simplement que possible. Je montrerai quelques moyens rapides pour créer un groupe de boutons radio.
Pour montrer comment tirer le meilleur parti des widgets, les exemples vont commencer à devenir un peu plus compliqués. Vous devriez maintenant connaître les bases de leur création et comment spécifier des options lors de cette phase. Je dirai souvent qu'une option fonctionne exactement comme avec le widget X et je vous renverrai au chapitre qui concerne ce dernier pour des explications plus complètes.
Les boutons radio ressemblent aux cases à cocher : comme elles, ils ont aussi une variable associée à l'état de l'indicateur (à l'aide de l'option -variable). Lorsque vous créez un groupe de boutons radio, utilisez la même variable pour tous les boutons du groupe. La valeur placée dans celle-ci changera en fonction du bouton sélectionné. Pour créer un autre groupe de boutons, il suffit d'associer une variable différente à celui-ci.
Comme chaque bouton radio du groupe pointe vers la même variable, les options -onvalue et -offvalue n'ont pas de raison d'être : -offvalue vaudrait ce que tout autre bouton voudrait qu'elle soit. Pour régler ce problème, les boutons radio utilisent l'option -value au lieu de -onvalue et -offvalue.
Comme premier exemple, nous allons créer un groupe de boutons radio indiquant la couleur de fond de notre fenêtre. Nous devons utiliser des couleurs correctes pour l'instruction $mw-
>
configure(-
background =>
couleur). En général, les noms simples de couleurs fonctionnent ; nous utiliserons donc les couleurs "red","yellow","green", "blue" et "gray" (qui sont les valeurs correspondant, respectivement, aux couleurs rouge, jaune, vert, bleu et gris).
Comme toujours, la création d'un bouton radio est réalisée par :
$br
=
$widgetparent-
>
Radiobutton( [ option =>
valeur, . . . ] )->
pack
;
Voici le code permettant de créer le groupe de boutons radio contrôlant la couleur du fond :
# configure la valeur par défaut souhaitée
$br_valeur
=
"blue"
;
$mw-
>
configure( -
background =>
$br_valeur
);
# hachage pour traduire les couleurs en français
%us_2_fr
=
(
red =>
'rouge'
,
yellow =>
'jaune'
,
green =>
'vert'
,
blue =>
'bleu'
,
grey =>
'gris'
);
# crée les boutons radio qui nous permettront de changer le fond
foreach ( keys
%us_2_fr
) {
$mw-
>
Radiobutton(
-
text =>
$us_2_fr
{
$_
}
,
-
value =>
$_
,
-
variable =>
\$br_valeur
,
-
command =>
\&
change_fond
)->
pack
( -
side =>
'left'
);
}
# fonction changeant la couleur du fond selon $br_valeur
sub change_fond {
print
"La couleur du fond est maintenant :
$us_2_fr{$br_valeur}\n
"
;
$mw-
>
configure( -
background =>
$br_valeur
);
}
Nous stockons l'état du groupe des boutons radio dans $br_valeur. Celle-ci est initialisée à « blue », ce qui correspond au premier bouton créé. Lorsque l'un des boutons est sélectionné, y compris celui qui est déjà coché, la fonction change_fond est appelée. Celle-ci affichera la nouvelle valeur de $br_valeur
, puis modifiera en conséquence la couleur de fond de notre fenêtre principale. Afin d'afficher le nom des couleurs en français, nous utilisons le hachage %us_2_fr
afin de mettre en relation la valeur qui sera utilisée pour l'option -background de configure (qui est le nom de la couleur en anglais : « blue », par exemple) avec la valeur de l'option -text du bouton radio (qui sera en français : « bleu », par exemple). C'est aussi le texte français qui sera affiché par l'instruction print.
Une chose à noter : bien que nous ayons positionné la valeur par défaut de notre groupe de boutons à « blue », cela ne signifie pas que le fond de la fenêtre ait été aussi coloré en bleu. Pour ce faire, nous appelons la méthode configure en lui passant le contenu de $br_valeur
. On aurait aussi pu faire la même chose en appelant explicitement la fonction change_fond, ou en coloriant la fenêtre lors de sa création.
La fenêtre obtenue est celle de la figure 4.11.
La meilleure façon de comprendre comment fonctionne cette fenêtre est de taper le code et de l'exécuter (ce conseil s'applique à beaucoup d'exemples de ce livre). Lorsque l'on clique sur chacun des boutons radio, on constate que les bandes de fenêtre, en haut et en bas, changent de couleur. On ne voit que ces petites bandes, car on a seulement modifié la couleur de fond de $mw
, pas celles des boutons radio ou du bouton « Fin ».
Maintenant que nous avons vu une application de base des boutons radio, nous pouvons passer en revue chacune de leurs options.
IV-B-2. Options des boutons radio ▲
Comme pour les cases à cocher, les options suivantes sont les mêmes pour les trois types de boutons : -activebackground, -activeforeground, -anchor, -background, -borderwidth, -cursor, -disabledforeground, -font, -foreground, -height, -highlightbackground, -highlightcolor,-highlightthickness,-padx, -pady, -state, -takefocus, -text, -textvariable, -underline, et -width.
De plus, les options suivantes sont les mêmes, que ce soit pour une case à cocher ou pour un bouton radio : -command, -indicatoron, -image, -selectimage, -bitmap, -wraplength, -justify et -selectcolor.
Je détaillerai les autres, car elles se comportent un peu différemment, du fait du contexte dans lequel on les utilise.
-activebackground => couleur
- Configure la couleur de fond qu'aura le widget lorsque la souris est au-dessus de lui.
-activeforeground => couleur
- Configure la couleur qu'aura le texte du widget lorsque la souris est au-dessus de lui.
-anchor => 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | 'center'
- Configure la position du texte dans le widget. L'effet de cette option est d'autant plus notable que le widget est agrandi.
-background => couleur
- Configure la couleur de fond du widget (derrière le texte).
-bitmap => nom_bitmap
- Affiche ce bitmap à la place du texte.
-borderwidth => montant
- Configure l'épaisseur des bords du widget. Modifie aussi l'épaisseur de l'indicateur. La valeur par défaut est 2.
-command => fct_rappel
- Associe une fonction au bouton. Appelée lorsque le bouton est cliqué.
-cursor => nom_curseur
- Indique que le curseur se transformera en nom_curseur lorsqu'il sera au-dessus du widget.
-disabledforeground => couleur
- Précise la couleur du texte lorsque -state est 'disabled'.
-font => nom_fonte
- Configure la fonte à utiliser pour afficher le texte dans le widget.
-foreground => couleur
- Précise la couleur du texte.
-height => montant
- Configure la hauteur du bouton. montant est une distance d'écran.
-highlightbackground => couleur
- Configure la couleur du rectangle situé autour du widget lorsque celui-ci n'a pas le focus.
-highlightcolor => couleur
- Configure la couleur du rectangle situé autour du widget lorsque celui-ci a le focus.
-highlightthickness => montant
- Configure la largeur du rectangle de focus.
-image => ptr_img
- Indique qu'une image sera mise à la place du texte.
-indicatoron => 0 | 1
- Précise l'état de l'indicateur : 0 signifie que celui-ci ne sera pas affiché.
-justify => 'center'| 'left' | 'right'
- Configure l'alignement du texte dans le widget.
-padx => montant
- Configure l'espace qui sera laissé entre le texte/indicateur et les bords gauche/droit du widget.
-pady => montant
- Configure l'espace qui sera laissé entre le texte/indicateur et les bords haut/bas du widget.
-relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken' | 'solid'
- Modifie l'aspect du contour du widget.
-selectcolor => couleur
- Précise la couleur que prendra l'indicateur lorsqu'il est coché.
-selectimage => ptr_img
- Précise qu'une image devra être affichée à la place du texte lorsque le bouton est activé. Cette option est sans effet si -image n'est pas utilisée.
-state => 'normal' | 'active' | 'disabled'
- Configure l'état du widget. Si cette option vaut 'disabled', le bouton radio ne répondra à aucune entrée.
-takefocus => 0 | 1 | undef
- Précise si le widget sera disponible pour prendre le focus ou non.
-text => chaîne
- Indique le texte qui sera affiché dans le widget.
-textvariable => \$variable
- Précise que le texte contenu dans
$variable
sera affiché dans le widget.
-underline => n
- Souligne le nième caractère du texte du widget.
-value => valeur
- Met valeur dans la variable spécifiée par -variable lorsque ce bouton radio est sélectionné (la valeur par défaut est 1).
-variable => \$variable
- Précise la variable à utiliser lorsque le bouton radio est cliqué.
-width => montant
- Donne la largeur du widget. montant est une distance d'écran.
-wraplength => montant
- Force un retour à la ligne du texte lorsqu'il dépasse ce montant.
IV-B-3. Utilisation de l'option -variable▲
L'option -variable aura le même aspect dans toutes les instructions de création de boutons radio sauf, qu'évidemment, on ne l'utilise pas de la même façon que pour les autres widgets. Plusieurs boutons radio peuvent partager la même variable plutôt que chacun ait sa propre variable distincte. L'exemple de la figure 4.11 montre comment cela fonctionne.
IV-B-4. Configuration de la valeur d'un bouton radio ▲
Une case à cocher avait deux options, -onvalue et -offvalue, car l'on devait se soucier de l'état de chacune des cases en particulier. Dans le cas des boutons radio, on ne s'occupe que de l'état d'un groupe entier. Chaque bouton radio doit avoir une valeur différente pour son option -value afin que l'examen de la variable désignée par -variable nous indique quel est le bouton sélectionné.
La valeur par défaut de -value est 1 (rappelez-vous : lorsque vous avez un groupe ne contenant qu'un seul bouton radio, celui-ci est toujours sélectionné).
Pour nous assurer que vous avez compris la différence existant entre les options -variable et -value, prenons un court exemple.
$mw-
>
Radiobutton(
-
text =>
"Boeuf"
,
-
value =>
"Boeuf"
,
-
variable =>
\$plat
);
$mw-
>
Radiobutton(
-
text =>
"Poulet"
,
-
value =>
"Poulet"
,
-
variable =>
\$plat
);
$mw-
>
Radiobutton(
-
text =>
"Végétarien"
,
-
value =>
"Végétarien"
,
-
variable =>
\$plat
);
Nous avons ainsi créé trois boutons radio utilisant tous la variable $plat
pour y stocker leur valeur. Si l'utilisateur choisit « Bœuf », $plat
contiendra la valeur « Bœuf », s'il choisit « Poulet », $plat
contiendra la valeur « Poulet ». Plus tard, lorsque nous construirons le menu du jour afin de l'imprimer, nous pourrons consulter $plat
afin de savoir ce que l'utilisateur souhaite commander.
IV-B-5. Style d'un bouton radio ▲
Bon, d'accord… l'option -relief fait la même chose qu'avec une case à cocher, mais cela vaut la peine de voir une copie d'écran montrant ce qui se passe lorsque l'on utilise les différents types de contours (voir la figure 4.12).
Comme pour une case à cocher, la modification de -borderwidth peut changer radicalement l'aspect du bouton (voir la figure 4.13).
Vous vous rappelez comment l'indicateur disparaissait complètement d'une case à cocher lorsque l'on utilisait une valeur de 10 pour -borderwidth ? Eh bien, avec un bouton radio, cela le fait un peu ressembler à un cerf-volant (voir la figure 4.14). Vous ne pourrez pas non plus dire quel bouton est sélectionné ou pas, aussi je vous conseille de ne pas utiliser cette option.
IV-B-6. Configuration d'un bouton radio ▲
Exactement comme avec nos autres widgets, on peut utiliser configure et cget pour obtenir, ou configurer, les valeurs des options de chaque bouton radio. Voir l'annexe A pour plus de détails sur l'utilisation de ces deux méthodes.
IV-B-7. Sélection et désélection d'un bouton radio ▲
Un bouton radio dispose aussi des méthodes select et deselect :
$br-
>
deselect();
$br-
>
select
();
L'utilisation de select sélectionne le bouton radio et deselect le désélectionne (elle affecte une chaîne vide à la variable associée à -variable : si vous utilisez cette méthode, assurez-vous d'en tenir compte dans toutes les lignes de code évaluant cette variable). La commande associée à l'option -command sera aussi appelée, que ce soit avec select ou deselect.
IV-B-8. Clignotement d'un bouton radio ▲
La méthode flash fera clignoter la couleur de fond et la couleur du texte du bouton radio. À part ça, elle ne fait rien d'intéressant.
$br-
>
flash();
IV-B-9. Invocation d'un bouton radio ▲
Pour sélectionner un bouton radio par programme, on utilise la méthode invoke :
$br-
>
invoke();
Cela sélectionnera le bouton radio et appellera aussi la fonction de rappel associée à celui-ci via l'option -command. Cela fait la même chose que lorsque l'on clique sur le bouton radio avec la souris.
IV-C. Essayez et amusez-vous !▲
- créez un ensemble de cases à cocher et un bouton « Go », énumérant les états de chaque case ;
- réalisez un questionnaire utilisant des cases à cocher pour les questions pouvant avoir une ou plusieurs réponses, et des boutons radio pour les questions n'en admettant qu'une ;
- créez trois groupes de cases à cocher : « Couleur favorite », « Musique préférée » et « Pointure ». Puis, créez un bouton radio pour représenter chacun de ces groupes. Le bouton sélectionné décidera des cases à cocher que l'utilisateur pourra voir et utiliser.