XII. Cadres▲
Un widget cadre est, au premier abord, peu excitant. Il ne fait qu'offrir un emplacement où d'autres widgets pourront se trouver ; cela semble anodin, mais ne l'est pas. Les gestionnaires d'espace de Perl/Tk présentent quelques limites (voir le chapitre 2, Gestion de l'espace), et les cadres peuvent les aider à mieux fonctionner. Dans ce chapitre, nous utiliserons pack en tant qu'exemple de gestionnaire d'espace, car c'est le plus employé, mais ne négligez pas que les règles générales d'utilisation d'un cadre s'appliquent aussi aux autres gestionnaires.
La raison d'être d'un widget cadre est de contenir d'autres widgets, et de s'adapter à la taille de ceux-ci. Un cadre ne contenant pas de widget est invisible. Si la taille des widgets qu'il contient est modifiée pour une raison quelconque, le cadre tentera d'adapter ses dimensions en conséquence (en devenant plus grand ou plus petit)(34).
XII-A. Création d'un cadre▲
On utilise la méthode Frame sur le widget parent du cadre à créer :
$cadre
=
$parent-
>
Frame( [ option =>
valeur, ... ] )->
pack
();
$parent est soit une fenêtre, soit un widget de premier niveau, soit un autre cadre(35). Après sa création, le cadre peut devenir parent d'autres widgets ; pour cela, il n'a pas besoin d'avoir été placé à l'écran. On peut très bien placer des widgets dans un cadre : ceux-ci ne s'afficheront que lorsqu'on aura demandé au cadre lui-même de se placer à l'écran.
Comme avec tous les autres widgets de Perl/Tk, les options utilisées avec la méthode Frame modifient l'aspect du cadre dans la fenêtre. Le widget cadre n'accepte que quelques options, toutes très simples, présentées ci-dessous :
-background => couleur
- Fixe la couleur du fond du cadre (il n'y a pas de premier plan).
-borderwidth => montant
- Configure la largeur du contour du cadre. Par défaut, celle-ci est de 0 pixel.
-class => nom_classe
- Indique quelle sera la classe associée au cadre dans la base de données des options (voir la section concernant cette base de données du chapitre 16, Méthodes communes à tous les widgets). Cette option n'est, en fait, pas spécifique aux cadres et tous les widgets peuvent l'utiliser.
-colormap => "new" | $fenetre
- Indique si le cadre doit utiliser une nouvelle palette de couleurs ou en partager une avec un autre widget de l'application. Par défaut, cette option n'est pas définie, ce qui implique que le cadre utilisera la même palette que son parent.
-container => 0 | 1
- Cette option n'existe qu'avec Tk8.0. Si elle est vraie, le cadre servira à contenir une application imbriquée.
-cursor => nom_curseur
- Modifie le curseur utilisé lorsque le pointeur de la souris se trouvera au-dessus du cadre.
-height => montant
- Fixe la hauteur du cadre. montant est exprimé en distances d'écran.
-highlightbackground => couleur
- Configure la couleur qu'aura le rectangle de focus lorsque le cadre n'aura pas le focus clavier.
-highlightcolor => couleur
- Configure la couleur qu'aura le rectangle de focus lorsque le cadre aura le focus clavier. Par défaut : noir.
-highlightthickness => montant
- Fixe l'épaisseur du rectangle de focus ; par défaut, celle-ci est nulle.
-label => chaîne
- Ajoute une étiquette au cadre. Le texte affiché sera chaîne.
-labelPack => [ options de placement ]
- Précise les options de placements que l'étiquette devra utiliser.
-labelVariable => \$variable
- Indique la variable qui contiendra le texte de l'étiquette.
-relief => 'flat' |'groove' | 'raised' |'ridge' | 'sunken' |'solid'
- Modifie l'apparence du contour du widget. La valeur par défaut est 'flat'.
-takefocus => 0 | 1 | undef
- Indique si le cadre pourra recevoir le focus. Par défaut, il ne le peut pas.
-visual => "type #"
- Utilisée avec X Window, cette option modifie le nombre de couleurs disponibles pour votre application. Elle n'a pas d'effet avec les systèmes Win32.
-width => montant
- Fixe la largeur initiale du cadre, exprimée en distances d'écran.
XII-B. Styles des cadres▲
Comme pour tous les widgets, les options -relief et -borderwidth modifient l'aspect du contour d'un cadre. La valeur par défaut de -relief est 'flat' et celle de -borderwidth est 0. Si l'on souhaite que le cadre ait un contour visible, on doit s'assurer que cette dernière option soit supérieure à 0 mais, dans tous les cas, vous ne verrez rien tant que le cadre ne contiendra pas de widget. Ainsi, pour les exemples de la figure 12.1, on a ajouté une étiquette et une zone de saisie afin de mettre en évidence le contour de chaque cadre. On notera que l'étiquette a été créée à l'aide de Label et que nous n'avons pas utilisé l'option -label, étudiée dans la section suivante.
L'utilisation de -relief et -borderwidth est un bon moyen de mettre en évidence un cadre dans une fenêtre car, lorsque celle-ci contient beaucoup de widgets, il n'est pas facile de mémoriser où se trouvent les cadres. Pour contourner ce problème, j'utilise souvent ces options avec les valeurs 'groove' et 5, respectivement.
XII-B-1. Ajout d'une étiquette à un cadre ▲
On ajoute une étiquette à un cadre avec l'option -label, qui prend une chaîne comme valeur :
$mw-
>
Frame(-
label =>
"Mon cadre :"
)->
pack
;
...
# On peut aussi configurer l'étiquette plus tard :
$cadre-
>
configure(-
label =>
"Mon cadre :"
)->
pack
;
Par défaut, l'étiquette est placée en haut du cadre, centrée dans le sens de la largeur, comme le montre la figure 12.2. On a placé un bouton classique dans le cadre afin que ce dernier soit visible. Le cadre lui-même utilise les options -
relief =>
'groove'
et -
borderwidth =>
2
afin de bien délimiter son contour.
L'emplacement de l'étiquette dans le cadre dépend de l'option -labelPack. Celle-ci a pour valeur un tableau anonyme contenant les options de placement de l'étiquette :
-
labelPack =>
[ -
side =>
'left'
, -
anchor =>
'w'
]
On notera qu'il n'existe pas d'option -labelGrid et qu'il faut utiliser pack pour placer les widgets dans un cadre utilisant l'option -label sinon l'application ne fonctionnera pas correctement (voire pas du tout).
Au lieu d'utiliser une chaîne littérale pour l'étiquette, on peut utiliser une variable à l'aide de l'option -labelVariable :
-
labelVariable =>
\$var_texte
Lorsque le contenu de \$var_texte
sera modifié, l'étiquette du cadre le sera aussi.
Dès que l'on utilise -label ou -labelVariable, une étiquette est créée et placée dans le cadre. Ces options peuvent être employées dans l'appel initial à Frame ou plus tard, à l'aide de $cadre-
>
configure( ... ). Dans ce dernier cas, l'étiquette sera placée au-dessus de tous les autres widgets contenus par le cadre.
XII-C. Les cadres ne sont pas interactifs▲
Un cadre n'est pas un widget interactif ; par défaut, il n'accepte aucune entrée de la part de l'utilisateur. Les widgets qu'ils contiennent le peuvent, mais pas le cadre lui- même. Comme toujours, la gestion du focus est contrôlée par l'option -takefocus :
-
takefocus =>
0
Pour les cadres, cette option vaut 0. Si, pour une raison quelconque, vous voulez que l'utilisateur puisse interagir avec le cadre, il suffit d'utiliser -
takefocus =>
1
.
XII-D. Problèmes avec les palettes de couleurs ▲
Lorsque plusieurs applications s'exécutent simultanément, et que l'on lance le navigateur de Netscape, on note parfois que les couleurs sont perturbées. Lorsque l'on passe d'une application au navigateur, les couleurs des autres applications changent soudainement. Si l'on repasse du navigateur à une application, ce sont celles du navigateur qui sont affectées. Ces problèmes sont dus au fait que le navigateur est un gouffre à couleurs ; il a demandé plus de couleurs que le système d'exploitation ne peut en fournir à l'ensemble des applications employées sur le moment. Celui-ci doit alors modifier la palette de couleurs des applications afin de permettre à celle qui est active de disposer des couleurs voulues, aux dépens des autres. Cette palette sert au système d'exploitation pour mémoriser qui utilise quelles couleurs.
Les applications Perl/Tk peuvent aussi être multicolores - on peut donner dans le clinquant et attribuer une couleur à chaque bouton. Cela posera des problèmes si d'autres applications en cours d'exécution utilisent aussi un grand nombre de couleurs ; en ce cas, Perl/Tk basculera en mode monochrome. Si l'on n'apprécie pas ce comportement, l'option -colormap permet de s'en affranchir. Elle prend comme paramètre le mot "new" ou une référence à une autre fenêtre. Dans le premier cas, l'application créera sa propre palette. Si vous utilisez l'option avec une autre fenêtre, les deux fenêtres partageront la palette. Mais il y a une entourloupette, sous la forme de l'option -visual. L'option -visual prend pour valeur une chaîne contenant un mot-clé et un nombre ; par exemple :
-
visual =>
"staticgrey 2"
Le mot-clé peut être : staticgrey, greyscale, staticcolor, pseudocolor, truecolor, ou directcolor. Le nombre sert à préciser le nombre de couleurs utilisées (2 = noir et blanc).
Lorsque que l'on utilise -colormap pour partager la palette de couleurs entre deux fenêtres, celles-ci doivent avoir la même option -visual. Ceci signifie que -visual doit être indéfini pour les deux fenêtres, ou contenir la même valeur. La méthode configure ne permet pas de modifier -colormap, ni -visual.
Vous rencontrerez aussi les options -colormap et -visual au chapitre 13, Widgets de premier niveau. Nous les avons d'abord évoquées ici, car c'est la première fois que nous en avons l'utilité. Pour être honnête, vous n'utiliserez probablement jamais ces deux options avec quelque widget que ce soit.
XII-D-1. L'option magique -class ▲
Cette option vous permet de créer un cadre dont le type ne sera pas la classe Frame.
Il suffit de lui fournir une chaîne représentant un identificateur unique de classe :
-
class =>
"Mon_cadre"
Le chapitre 13 traite en détail des classes (et de leur utilité).
XII-E. Méthodes du widget Frame▲
Seules cget et configure sont disponibles pour un widget cadre. Celles-ci sont décrites à l'annexe A, Configuration des widgets avec configure et cget.
XII-F. Essayez et amusez-vous !▲
Lorsque l'on utilise la méthode Scrolled, on emploie des cadres sans même le savoir. Le widget ainsi créé est placé avec ses barres de défilement dans un cadre afin de pouvoir se comporter comme un widget unique. Voici quelques autres suggestions d'utilisation des cadres :
- créez plusieurs lignes contenant, chacune, une étiquette et une zone de saisie. Chaque « ligne » doit être dans son propre cadre pour apparaître proprement ;
- placez une image contre le bord de la fenêtre de votre application. Placez des widgets dans un cadre (à gauche ou à droite) et l'image de l'autre côté ;
- placez une boîte de liste avec une barre de défilement dans votre application, un cadre contenant trois boutons (OK, Annuler, Appliquer) en bas de la fenêtre ; ajoutez à droite un cadre contenant deux boutons (Supprimer, Ajouter) permettant de manipuler la liste. Avec les cadres, vous pouvez regrouper des boutons dans une zone unique au lieu de les placer avec d'autres boutons n'ayant pas de points communs avec eux.