VI. Barres de défilement▲
On utilise des barres de défilement (scrollbars, en anglais) avec des widgets lorsque l'espace d'affichage est plus petit que ce que l'on veut montrer. La présence d'une ou deux barres permet à l'utilisateur de faire défiler horizontalement et/ou verticalement le contenu d'un widget. Vous avez déjà rencontré des barres de défilement dans différents types d'applications : tout traitement de texte digne de ce nom, les logiciels de dessin, et même votre navigateur web, en possèdent. Ce chapitre vous expliquera comment utiliser les barres de défilement avec certains widgets Perl/Tk.
VI-A. Composantes d'une barre de défilement▲
La figure 6.1 présente les différentes parties d'une barre de défilement.
La zone de défilement (trough) est la partie creusée, située entre les deux flèches. Elle est divisée en deux parties par l'ascenseur (slider), zone 1 et zone 2. L'ascenseur est le rectangle indiquant de manière proportionnelle à quel niveau l'on se trouve dans le widget. Si l'on se trouvait à la moitié de celui-ci, l'ascenseur serait au milieu de la zone de défilement. Les flèches aux deux extrémités sont, ici, appelées arrow1 et arrow2 . Si la barre de défilement avait été verticale (tournée de 90 degrés dans le sens des aiguilles d'une montre), arrow1 aurait été la flèche du haut.
Si l'on clique sur l'une ou l'autre des deux flèches, l'information contenue dans le widget se déplacera unité par unité. La valeur de celle-ci dépend du type de widget auquel est associée la barre de défilement : dans le cas d'une zone de saisie, l'unité est le caractère, dans le cas d'une boîte de liste disposant d'une barre de défilement verticale, l'unité est la ligne. Si l'on clique dans l'une des deux zones de défilement qui se trouvent de part et d'autre de l'ascenseur, l'information contenue dans le widget défilera d'une hauteur ou d'une largeur de fenêtre, dans cette direction. On peut aussi cliquer directement sur l'ascenseur et, tout en maintenant le bouton de la souris enfoncé, le déplacer « manuellement ».
Les barres de défilement peuvent être horizontales ou verticales. Normalement, elles se trouvent en bas et/ou à droite du widget qu'elles permettent de parcourir, mais ce n'est pas toujours le cas.
Les widgets de Perl/Tk pouvant être configurés pour utiliser des barres de défilement sont les éditeurs de texte, les boîtes de liste, les canevas, les zones de saisie, les visualiseurs PostScript , les listes arborescentes et les damiers. Seuls les quatre premiers (éditeur de texte, boîte de liste, canevas et zone de saisie) sont traités dans ce livre. Les figures 6.2 à 6.5 contiennent des exemples de barres de défilement associées à chacun de ces widgets.
Il y a deux façons de créer et configurer des barres de défilement pour les associer à des widgets. On peut utiliser la méthode Scrollbar afin de créer un widget barre de défilement, ou Scrolled afin de créer un widget et ses barres de défilement associées. Chacune d'elles a ses avantages et ses inconvénients. L'utilisation de Scrolled nécessite beaucoup moins de travail et de lignes de programme, mais ne vous permettra pas de créer n'importe quelle fioriture, comme associer la même barre de défilement à deux widgets différents. Créer vous-même les barres de défilement implique plus de code, mais vous permet de vous amuser beaucoup plus avec elles, car, si nécessaire, vous contrôlerez directement leur emplacement et les widgets auxquels elles seront associées. Ce chapitre présente ces deux méthodes de création.
VI-B. La méthode Scrolled ▲
On utilise la méthode Scrolled pour créer en même temps un widget et ses barres de défilement. Elle renvoie un pointeur vers le widget créé. Il s'agit de la façon la plus simple d'ajouter des barres de défilement à un widget pouvant être parcouru. Cette méthode crée un cadre contenant le widget et la ou les barres de défilement. Tout cela est créé en un seul appel.
L'utilisation de Scrolled est la suivante :
$widget
=
$parent-
>
Scrolled('Widget'
, -
scrollbars =>
'chaîne'
[, options ] );
Le premier paramètre est le widget à créer : « Listbox » ou « Canvas », par exemple. L'autre paramètre nécessaire est l'option -scrollbars, qui prend pour valeur une chaîne indiquant les barres de défilement à créer et leurs emplacements.
Les valeurs possibles de -scrollbars sont "n", "s", "e", "w", "on", "os", "oe", "ow", ou toute combinaison de celles-ci comprenant n ou s avec e ou w. Le "n" demande de placer une barre de défilement horizontale au-dessus du widget. Un "s" demande de la placer en dessous. Un "e" placera une barre de défilement verticale à droite du widget et "w" la placera à gauche. Le lecteur perspicace aura compris que chacune des lettres "n", "s", "e" et "w" désigne un point cardinal (nord, sud, est, ouest).
En tout et pour tout, on ne peut placer que deux barres de défilement par widget, et elles doivent être perpendiculaires. On peut créer, par exemple, une seule barre de défilement sur le bord "n" du widget. On peut aussi en créer deux avec "nw" : une au-dessus, et l'autre à gauche du widget. Il n'est pas possible d'utiliser la valeur "ns", par exemple, car l'axe de parcours de "n" et "s" est le même.
Un "o" devant une direction rend cette barre de défilement optionnelle : elle ne s'affichera que si la taille du widget impose de faire défiler l'information qu'il contient. Mettez toujours les valeurs nord ou sud en premier (si vous les utilisez) afin d'éviter les messages émis par la fonction. Voici quelques exemples qui rendront tout cela plus clair :
# Crée une barre de défilement optionnelle
# à l'est (à droite) du widget
$bl
=
$mw-
>
Scrolled("Listbox"
, -
scrollbars =>
'oe'
)->
pack
;
# Crée des barres de défilement au sud (en dessous)
# et à l'est (à droite) du widget
$bl
=
$mw-
>
Scrolled("Listbox"
, -
scrollbars =>
'se'
)->
pack
;
# Créer des barres de défilement optionnelles au sud (en dessous)
# et à l'est (à droite) du widget
$bl
=
$mw-
>
Scrolled("Listbox"
, -
scrollbars =>
'osoe'
)->
pack
;
# Crée des barres de défilement au nord (au-dessus)
# et à l'ouest (à gauche) du widget
$bl
=
$mw-
>
Scrolled("Listbox"
, -
scrollbars =>
'nw'
)->
pack
;
VI-B-1. Configuration de barres créées avec Scrolled ▲
Toutes les autres options utilisées avec la méthode Scrolled ne servent qu'à configurer le widget créé. Si l'on veut configurer les barres de défilement, on utilisera la méthode Subwidget du widget de référence. Cette méthode peut être utilisée, car un widget Scrolled est en fait un widget composite. Ces widgets sont traités au chapitre 15, Widgets composites.
Pour colorer le fond de la barre de défilement horizontale en vert, on peut utiliser cette instruction :
$bl-
>
Subwidget("xscrollbar"
)->
configure(-
background =>
"green"
);
Pour configurer une barre verticale, on utilisera le paramètre "yscrollbar" au lieu de "xscrollbar". Si l'on tente de configurer une barre de défilement qui n'a pas été créée (si, par exemple, on a utilisé l'option -
scrollbars =>
"e"
et que l'on utilise "xscrollbar" pour la configurer), rien ne se passera.
Pour ne configurer que le widget, on utilisera $widget-
>
configure() après avoir appelé Scrolled, mais on peut aussi écrire :
$widget-
>
Subwidget("widget"
)->
configure(...);
Cette utilisation de Subwidget est idiote, car on pourrait se contenter de $widget
. La chaîne « widget » est la même que le premier paramètre passé à Scrolled, sauf qu'il est entièrement en minuscules. Dans les exemples précédents, par exemple, nous avons appelé Scrolled en lui passant le paramètre "Listbox", mais nous utiliserions "listbox" avec la méthode Subwidget.
VI-C. Le widget Scrollbar▲
Au lieu de créer automatiquement une ou plusieurs barres de défilement avec la méthode Scrolled, on peut utiliser la méthode de création Scrollbar et configurer ce widget nous-même. Cette façon de procéder est préférable lorsque l'on doit faire des choses non classiques, comme utiliser une seule barre de défilement pour parcourir deux boîtes de liste.
VI-C-1. Création d'un widget barre de défilement ▲
Pour créer la barre, on appelle la méthode Scrollbar à partir du widget parent. Elle renvoie une référence à la barre de défilement ainsi créée, référence qui pourra être ensuite utilisée pour la configuration de la barre.
$defilement
=
$mw-
>
Scrollbar([ options ...] )
On doit faire au moins deux autres opérations afin qu'une barre de défilement fonctionne avec un autre widget. Il faut d'abord créer le widget à parcourir, qui utilisera la barre à l'aide de ses options -xscrollcommand ou -yscrollcommand. Puis, on doit configurer la barre de défilement pour qu'elle sache communiquer avec ce widget. Voici un exemple créant une boîte de liste (ne vous inquiétez pas si vous ne comprenez pas encore tout : je veux juste montrer un exemple complet avant de présenter toutes les options) :
# Création d'un barre de défilement verticale
$defil_v
=
$mw-
>
Scrollbar();
$liste
=
$mw-
>
Listbox(-
yscrollcommand =>
['set'
=>
$defil_v
]);
# Configuration de la barre pour qu'elle communique avec la liste
$defil_v-
>
configure(-
command =>
['yview'
=>
$liste
]);
# On place d'abord la barre pour qu'elle ne disparaisse pas lorsque l'on
# modifie la taille de la liste
$defil_v-
>
pack
(-
side =>
'right'
, -
fill =>
'y'
);
$liste-
>
pack
(-
side =>
'left'
, -
fill =>
'both'
);
La création de la barre de défilement est très simple : nous utilisons toutes les valeurs par défaut de ses options. Comme nous créons une liste, nous devons utiliser une fonction de rappel pour que cette liste puisse communiquer avec la barre de défilement lorsque son contenu est parcouru. Notre barre est verticale, par conséquent c'est l'option -yscrollcommand qui utilise la commande set et notre barre qui lui est assignée (si elle avait été horizontale, on aurait utilisé -xscrollcommand). Lorsque le contenu de la liste est parcouru par l'utilisateur sans utiliser la barre de défilement, la liste alertera la barre en invoquant $defil_v-
>
set(...).
La ligne $defil_v-
>
configure(-
command =>
['yview'
=>
$liste
]) fait quasiment le contraire ; elle configure la barre de défilement pour qu'elle communique avec la boîte de liste. Lorsque l'utilisateur clique sur la barre, celle-ci appellera $liste-
>
yview(...) pour demander à la liste de modifier la vue de son contenu. On utilise la version « y » de la méthode, car il s'agit d'une barre de défilement verticale.
Vous trouverez plus de détails sur yview dans la section qui lui est consacrée, plus loin dans ce chapitre. Les deux dernières lignes de l'exemple placent la barre et la liste dans la fenêtre de façon à ce qu'elles aient la même hauteur, et que la barre soit à droite de la liste.
Placez toujours d'abord vos barres de défilement dans la fenêtre ou le cadre : elles resteront visibles lorsque l'utilisateur réduira la fenêtre. Cela changera alors la taille de la liste (ou de tout autre widget utilisé), mais laissera les barres visibles sur les bords de l'écran.
Maintenant que nous avons vu un exemple complet de création d'une barre de défilement et de configuration du widget à parcourir, on peut passer les options en revue, en ayant déjà une petite idée de leurs utilisations.
VI-C-2. Options des barres de défilement ▲
Cette liste énumère les options possibles d'une barre de défilement, et en donne de brèves définitions. Les options importantes sont détaillées plus loin dans ce chapitre.
-activebackground => couleur
- Configure la couleur que prendra la barre de défilement lorsque le pointeur de la souris passe au-dessus.
-activerelief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken'
- Détermine l'aspect des éléments actifs. Cette option concerne les flèches des extrémités et l'ascenseur.
-background => couleur
- Configure la couleur de fond de la barre de défilement (la couleur de la zone de défilement n'est pas concernée).
-borderwidth => montant
- Configure la largeur des bords de la barre, des flèches et de l'ascenseur.
-command => fct_rappel
- Précise la fonction qui sera appelée lorsque l'on clique sur la barre de défilement.
-cursor => nom_curseur
- Configure le curseur qui s'affichera lorsque le pointeur de la souris est au-dessus de la barre de défilement.
-elementborderwidth => montant
- Configure la largeur des bords des flèches et de l'ascenseur.
-highlightbackground => couleur
- Configure la couleur que prendra le rectangle de focus autour de la barre de défilement lorsque celle-ci n'a pas le focus clavier.
-highlightcolor => couleur
- Configure la couleur que prendra le rectangle de focus autour de la barre de défilement lorsque celle-ci a le focus clavier.
-highlightthickness => montant
- Configure l'épaisseur du rectangle de focus. La valeur par défaut est 2.
-jump => 0 | 1
- Indique si la barre de défilement « sautera » ou non.
-orient => "horizontal" | "vertical"
- Précise l'orientation de la barre de défilement.
-relief => 'flat' | 'groove' | 'raised' | 'ridge' | 'sunken' | 'solid'
- Modifie les contours du widget.
-repeatdelay => millisecondes
- Précise le nombre de millisecondes pendant lequel il faut presser une flèche avant qu'elle ne passe en répétition automatique. La valeur par défaut est 300 ms.
-repeatinterval => millisecondes
- Précise le nombre de millisecondes entre les répétitions automatiques. La valeur par défaut est 100 ms.
-takefocus => 0 | 1 | undef
- Indique si la barre de défilement pourra obtenir le focus clavier.
-troughcolor => couleur
- Modifie la couleur de la zone de défilement (des deux côtés de l'ascenseur).
-width => montant
- Configure la largeur de la barre de défilement.
VI-C-3. Couleurs d'une barre de défilement▲
Une barre de défilement contient une nouvelle partie de widget : la zone de défilement, qui se trouve derrière les flèches et l'ascenseur. Cette zone possède sa propre coloration grâce à l'option -troughcolor. La figure 6.6 en est un exemple.
Le fond de la barre est formé des flèches, de l'ascenseur et de ce qui entoure la zone de défilement. L'option -background permet de modifier la couleur du fond et l'option -activebackground contrôle la couleur qui sera utilisée lorsque le curseur de la souris est au-dessus des flèches ou de l'ascenseur. La figure 6.7 montre deux exemples : le premier n'utilise que -background, le deuxième lui ajoute -troughcolor.
VI-C-4. Style des barres de défilement ▲
Les options -relief et -borderwidth agissent sur les contours de la barre de défilement, des flèches et de l'ascenseur. Cela fonctionne de la même façon qu'avec les cases à cocher et les boutons radio. La figure 6.8 montre une copie d'écran des effets de différentes valeurs de ces deux options.
L'option -activerelief affecte la décoration des flèches et de l'ascenseur lorsque le curseur de la souris est au-dessus d'eux. L'option -elementborderwidth affecte ces mêmes éléments en permettant de changer leur largeur. L'option -borderwidth fait de même, mais modifie également les contours du widget. Remarquez comment le contour de la barre de défilement est restée à 2 dans la figure 6.9.
La largeur d'une barre de défilement, définie par l'option -width, est la distance de la partie étroite de la barre, sans les bords. La figure 6.10 montre les modifications de la barre lorsque l'on change la valeur de -width.
VI-C-5. Orientation d'une barre de défilement ▲
Comme nous l'avons écrit plus haut, une barre de défilement peut être verticale (ce qui est l'orientation par défaut) ou horizontale. Pour modifier cela, on utilise l'option -orient :
$defil_h
=
$mw-
>
Scrollbar(-
orient =>
'horizontal'
);
On peut aussi utiliser -
orient =>
'vertical'
, mais comme il s'agit du comportement par défaut, cela n'est pas nécessaire.
VI-C-6. Utilisation des flèches et de l'ascenseur ▲
Lorsque l'on clique sur l'une des flèches d'une barre de défilement, cela déplace l'ascenseur d'une unité dans cette direction. Si l'on continue de presser le bouton de la souris pendant un certain temps, l'ascenseur répétera automatiquement son mouvement. Le délai d'attente avant le démarrage de la répétition automatique est déterminé par l'option -repeatdelay : par défaut, il est de 300 millisecondes.
Lorsque l'on a maintenu suffisamment longtemps le bouton de la souris enfoncé afin de déclencher la répétition automatique, un court délai intervient entre chaque répétition de l'action. Ce délai est contrôlé par l'option -repeatinterval, qui vaut 100 millisecondes par défaut.
Normalement, le fait de cliquer sur l'ascenseur et de le bouger déplace aussi les données affichées dans le widget. C'est parce que la barre de défilement met continuellement à jour le widget pendant que l'on déplace l'ascenseur. Pour faire en sorte que la barre ne mette le widget à jour que lorsque l'on abandonne l'ascenseur, on utilise l'option -jump et on la met à 1 (sa valeur par défaut est 0). On utilisera -
jump =>
1
lorsque le widget à parcourir contient beaucoup de données, et que le fait d'attendre que l'écran se mette à jour lorsque l'on se déplace dans ces données donnerait l'impression d'une application lente.
VI-C-7. Assignation d'une fonction de rappel ▲
Lorsque l'on crée une barre de défilement, on lui indique le widget avec lequel communiquer, ainsi que la méthode de celui-ci qu'il convient d'appeler grâce à l'option -command, à laquelle on affecte une liste anonyme. Cette liste contient le nom de la méthode à appeler et le widget à partir duquel cette méthode doit être appelée. Dans l'exemple qui suit, on peut voir que nous souhaitons utiliser la méthode yview pour parcourir le widget $liste (une boîte de liste) :
$defil_v-
>
configure(-
command =>
['yview'
=>
$liste
]);
Lorsque l'utilisateur cliquera sur cette barre de défilement, cela appellera $liste-
>
yview. Nous savons que la barre associée à $liste
est verticale, car elle utilise la méthode yview ; pour une barre horizontale, on aurait utilisé xview. Ces deux méthodes demandent au widget de déplacer son contenu d'un montant déterminé par l'emplacement sur lequel a cliqué l'utilisateur dans la barre. Elles sont traitées dans la section suivante.
VI-C-8. Communication entre une barre de défilement et les autres widgets ▲
Comme nous l'avons déjà évoqué, nous utilisons l'option -command de la barre de défilement afin qu'elle sache quel widget et quelle méthode utiliser lorsque l'on clique dessus. La méthode sera xview pour les barres horizontales et yview pour les verticales. On peut appeler soi-même ces méthodes, mais, la plupart du temps, ce ne sera pas nécessaire.
xview et yview prennent le même type de paramètres. L'endroit de la barre sur lequel clique l'utilisateur déterminera la valeur utilisée, mais celle-ci sera toujours d'une des formes suivantes :
$widget-
>
xviewMoveto(fraction) ; # ou
$widget-
>
yviewMoveto(fraction) ;
Cette forme est utilisée lorsque l'utilisateur clique sur l'ascenseur, le déplace et le relâche. Le paramètre est une fraction, un nombre réel compris entre 0 et 1, représentant la première partie des données à afficher dans le widget. Si l'utilisateur déplace l'ascenseur jusqu'au sommet ou à l'extrême gauche de la barre, le tout début des données devrait apparaître à l'écran. Cela signifie que le paramètre devrait être 0 :
$widget-
>
xviewMoveto(0
);
Si l'ascenseur est déplacé au centre de la barre, le paramètre est 0.5 :
$widget-
>
xviewMoveto(0
.5
);
$widget-
>
xviewScroll(nombre, "units"
); # ou
$widget-
>
yviewScroll(nombre, "units"
);
Cette forme est utilisée lorsque l'utilisateur clique sur l'une des flèches de la barre. Le widget déplacera ses données vers le haut/bas ou vers la gauche/droite, unité par unité.
Le premier paramètre est le nombre d'unités à parcourir. Sa valeur peut être n'importe quel nombre, mais vaut généralement 1 ou -1. Une valeur de 1 signifie que la prochaine unité de donnée en bas ou à droite du widget deviendra visible (défilement d'une unité vers la gauche ou vers le haut). Une valeur de -1 signifie que l'unité de donnée précédente sera visible en haut ou à gauche du widget (une unité sera décalée du bas ou de la droite du widget). Par exemple, à chaque fois que l'utilisateur clique sur la flèche inférieure d'une barre verticale associée à une boîte de liste, une nouvelle ligne apparaît en bas de la liste.
Le deuxième paramètre est la chaîne « units ». Ce qu'elle signifie dépend du widget : pour une boîte de liste, l'unité est une seule ligne de texte, pour une zone de saisie, c'est un simple caractère.
Voici quelques exemples d'appels :
# L'utilisateur a cliqué sur la flèche inférieure
$liste-
>
yviewScroll(1
, "units"
);
# L'utilisateur a cliqué sur la flèche supérieure
$liste-
>
yviewScroll(-
1
, "units"
);
# L'utilisateur a cliqué sur la flèche droite
$saisie-
>
xviewScroll(1
, "units"
);
$widget-
>
xviewScroll(nombre, "page"
); # ou
$widget-
>
yviewScroll(nombre, "page"
);
Cette forme est exactement la même que la précédente, sauf le dernier paramètre, qui est « page » au lieu de « units ». Lorsque l'utilisateur clique sur la zone de défilement de la barre (entre l'ascenseur et les flèches), il s'attend à ce que les données soient déplacées d'une page entière. Ce qu'est une page dépend du widget parcouru. Pour une boîte de liste, par exemple, une page verticale est le nombre de lignes de la liste, une page horizontale est la largeur de cette liste.
VI-C-9. Configuration d'une barre de défilement ▲
On peut connaître et positionner n'importe quelle option d'une barre de défilement à l'aide de cget et configure. Voyez l'annexe A, Configuration des widgets avec configure et cget, pour les détails complets de ces méthodes.
VI-C-10. Définir ce qui est visible ▲
La méthode set, que l'on a évoquée lors de la création d'un widget avec barre de défilement, définit ce qui est visible. Dans notre premier exemple, nous avions créé une boîte de liste et lui avions demandé d'utiliser notre barre de défilement grâce à la méthode set :
$defil_v
=
$mw-
>
Scrollbar(); # Barre de défilement verticale
$liste
=
$mw-
>
Listbox(-
yscrollcommand =>
['set'
=>
$defil_v
]);
Lorsque le widget appelle la méthode set, il lui passe deux fractions (premier et dernier) en paramètres :
$defil_v-
>
set(premier, dernier);
Cela change la position de que nous voyons des données. Les paramètres premier et dernier sont des nombres réels compris entre 0 et 1. Ils représentent, respectivement, la position du premier et du dernier élément des données visibles. Si nous pouvons voir toutes les données de notre widget, ils vaudront 0 et 1. La première valeur deviendra plus grande au fur et à mesure que des données supplémentaires disparaissent vers le haut, et la deuxième deviendra plus petite au fur et à mesure que des données supplémentaires disparaissent vers le bas. Vous ne rencontrerez probablement jamais de situations dans lesquelles vous devrez appeler set vous-même, mais essayez simplement d'avoir une idée de ce qui se passe en coulisses.
La figure 6.11 montre un document imaginaire, visualisé dans un widget parcouru verticalement. Le rectangle en pointillés représente ce qui est vu actuellement dans le widget. Lorsque celui-ci appelle set, il détermine la position du premier élément visible et le passe comme premier paramètre. Ici, ce serait 10 %, soit 0.10. Le second paramètre passé à set est la position du dernier élément de données visible du document. Dans notre exemple, ce serait 80 %, soit 0.8.
VI-C-11. Connaître la vue courante ▲
La méthode get retourne une liste contenant les dernières valeurs des paramètres que nous venons de décrire pour set :
($premier
, $dernier
) =
$defil_w-
>
get();
Ces données varient lorsque le widget ou la barre de défilement demandent une modification de la position des données.
VI-C-12. Activer les éléments d'une barre de défilement ▲
Pour savoir quelle partie de la barre de défilement est active, on peut utiliser la méthode activate :
$element
=
$defil_v-
>
activate();
La valeur renvoyée est une chaîne vide (ce qui signifie qu'aucun élément n'est actuellement actif) ou le nom de l'élément actif à ce moment-là. Les éléments possibles sont "arrow1", "arrow2", ou "slider", indiquant respectivement la flèche du haut (ou de gauche), la flèche du bas (ou de droite) et l'ascenseur.
Si vous passez à activate un nom d'élément comme paramètre, cet élément prendra les couleurs et l'aspect spécifiés par les options -activebackground et -activerelief. L'élément continuera de s'afficher dans cette couleur et avec ce style jusqu'à ce qu'un événement (comme le pointeur de la souris passant au-dessus de l'élément) provoque son changement. Contrairement à ce que l'on pourrait croire, l'utilisation d'activate n'invoque pas cet élément. Voici quelques exemples :
$defil_v-
>
activate("arrow1"
);
$defil_v-
>
activate("arrow2"
);
$defil_v-
>
activate("slider"
);
activate ne peut agir sur la zone de défilement, car celle-ci ne change pas de couleur lorsque la souris est au-dessus d'elle.
VI-C-13. Calcul des modifications en pixels ▲
Le nombre réel (positif ou négatif), renvoyé par la méthode delta, indique de combien doit changer la barre de défilement pour déplacer l'ascenseur de deltax pixels à droite pour les barres horizontales et de deltay pixels vers le bas pour les barres verticales (deltax sera ignoré pour les barres verticales, et deltay sera ignoré pour les barres horizontales).
$montant
=
$defil_v-
>
delta(deltax, deltay);
Le montant renvoyé est un pourcentage, positif ou négatif.
VI-C-14. Localiser un point de la zone de défilement ▲
Étant donné un point en (x, y), la méthode fraction renverra un nombre réel, compris entre 0 et 1 et indiquant où ce point se situera dans la zone de défilement de la barre :
$loc
=
$defil_v-
>
fraction(x
, y) ;
Le point (x, y) doit être exprimé relativement à la barre de défilement. La figure 6.12 montre l'emplacement de trois résultats possibles de fraction : 0 .0, 0.5, et 1.0.
VI-C-15. Identification des éléments ▲
La méthode identify renvoie une chaîne contenant le nom de l'élément situé aux coordonnées x, y :
$element
=
$defil_v-
>
identify(x
, y) ;
Si les coordonnées x et y ne correspondent à aucun élément, la chaîne renvoyée sera vide. x et y doivent être des coordonnées en pixels, exprimées relativement à la barre de défilement. Les noms d'éléments possibles sont "arrow1", "arrow2", "trough" (désignant la zone de défilement) et "slider" (ce dernier nom désignant l'ascenseur).
VI-D. Exemples▲
Nous présentons ici des exemples dans l'espoir de lever les confusions qui pourraient exister quant à la façon d'utiliser les barres de défilement dans le monde réel. Chaque exemple utilise, lorsque c'est possible, la méthode Scrolled ; puis on fait la même chose manuellement. Nous n'avons pas encore présenté tous les types de widgets utilisés ici, mais nous ne ferons rien de bien spécial avec eux. Si vous ne reconnaissez pas une méthode ou une option, consultez le chapitre traitant de ce widget pour en savoir plus.
VI-D-1. Zone de saisie ▲
Une zone de saisie ne peut être parcourue qu'horizontalement. Comme elle ne peut contenir qu'une seule ligne de texte au maximum, une barre de défilement verticale ne servirait à rien. La création d'une zone de saisie avec barre de défilement est facile avec Scrolled :
$mw-
>
Scrolled("Entry"
, -
scrollbars =>
"s"
, -
width =>
30
)->
pack
();
Si l'on souhaite que la barre de défilement ne s'affiche que lorsque les données de la zone de saisie le nécessitent, on utilise -
scrollbars =>
"os"
. L'utilisation de la méthode Scrollbar implique un peu plus de travail :
$defil_h
=
$mw-
>
Scrollbar(-
orient =>
'horizontal'
);
$saisie
=
$mw-
>
Entry(
-
width =>
30
,
-
xscrollcommand =>
['set'
, $defil_h
]);
$defil_h-
>
configure(-
command =>
['xview'
, $saisie
]);
$defil_h-
>
pack
(-
side =>
'bottom'
, -
fill =>
'x'
);
$saisie-
>
pack
(-
side =>
'bottom'
, -
fill =>
'x'
);
Les deux méthodes créeront une zone de saisie ressemblant à celle de la figure 6.13.
VI-D-2. Widgets liste, texte et canevas ▲
Un widget liste peut être parcouru horizontalement et verticalement, bien que l'on ne souhaite pas toujours utiliser ces deux possibilités. Si l'on connaît la largeur qu'auront les données et que l'on sait que la fenêtre pourra s'en accommoder, une barre horizontale n'est pas nécessaire. Notre premier exemple utilise la méthode Scrolled pour créer deux barres de défilement :
$mw-
>
Scrolled(
"Listbox"
,
-
scrollbars =>
"se"
,
-
width =>
50
,
-
height =>
12
)->
pack
();
Pour faire la même chose manuellement, il faut utiliser Scrollbar pour créer les deux barres, et les configurer pour qu'elles fonctionnent avec le widget :
$cadre
=
$mw-
>
Frame()->
pack
(
-
side =>
'top'
,
-
expand =>
1
,
-
fill =>
'both'
);
$defil_h
=
$cadre-
>
Scrollbar( -
orient =>
'horizontal'
);
$defil_v
=
$cadre-
>
Scrollbar();
$liste
=
$cadre-
>
Listbox(
-
width =>
50
,
-
height =>
12
,
-
yscrollcommand =>
[ 'set'
, $defil_v
],
-
xscrollcommand =>
[ 'set'
, $defil_h
]
);
$defil_h-
>
configure( -
command =>
[ 'xview'
, $liste
] );
$defil_v-
>
configure( -
command =>
[ 'yview'
, $liste
] );
$defil_h-
>
pack
( -
side =>
'bottom'
, -
fill =>
'x'
);
$defil_v-
>
pack
( -
side =>
'right'
, -
fill =>
'y'
);
$liste-
>
pack
( -
side =>
'bottom'
, -
fill =>
'both'
, -
expand =>
1
);
Comme vous pouvez le constater, l'utilisation de Scrolled économise beaucoup de travail. La figure 6.14 montre une liste avec deux barres de défilement : l'une au sud et l'autre à l'est. Cette fenêtre a été créée en utilisant Scrolled. Il existe une subtile différence : le petit espace carré à l'endroit où les deux barres se rencontrent, dans le coin inférieur droit. Lorsque l'on crée soi-même les barres, cet espace n'existe pas (la première barre de défilement placée occupera cet espace).
Les widgets texte et canevas avec barres de défilement sont créés exactement comme ci-dessus, nous n'allons donc pas perdre de temps à répéter le même code.
VI-D-3. Une seule barre de défilement, plusieurs widgets ▲
Parfois, on souhaite utiliser une seule barre de défilement avec plusieurs widgets. Lorsque l'utilisateur cliquera sur cette barre, cela fera défiler tous les widgets en même temps dans la même direction. Dans cet exemple, nous créerons trois listes, contenant chacune onze éléments. Une barre de défilement unique fera défiler les trois listes. Quelle que soit la liste sélectionnée par tabulation, son parcours via les flèches de la barre de défilement ou les touches 'PgUp' et 'PgDn' du clavier fera aussi défiler les autres listes. La figure 6.15 montre à quoi ressemblera la fenêtre.
Le code ayant permis de créer la fenêtre de la figure 6.15 est le suivant :
use Tk;
$mw
=
MainWindow->
new();
$mw-
>
title("Une seule barre/trois listes"
);
$mw-
>
Button(
-
text =>
"Fin"
,
-
command =>
sub {
exit }
)->
pack
( -
side =>
'bottom'
);
$defil_v
=
$mw-
>
Scrollbar();
# Tableau anonyme de trois widgets listes
$listes
=
[ $mw-
>
Listbox(), $mw-
>
Listbox(), $mw-
>
Listbox() ];
# Cette méthode est appelée lorsqu'une liste est parcourue avec le clavier
# La barre reflètera les changements et fera défiler les autres listes.
sub defiler_listes {
my ( $barre
, $parcouru
, $lsts
, @args
) =
@_
;
$barre-
>
set(@args
); # indique à la barre ce qu'il faut afficher
my ( $haut
, $bas
) =
$parcouru-
>
yview();
foreach $liste
(@$lsts
) {
$liste-
>
yview( moveto =>
$haut
); # ajuste chaque liste
}
}
# Configure chaque liste pour appeler &defiler_listes
foreach $liste
(@$listes
) {
$liste-
>
configure( -
yscrollcommand =>
[ \&
defiler_listes, $defil_v
, $liste
, $listes
] );
}
# Configure la barre pour faire défiler chaque liste
$defil_v-
>
configure(
-
command =>
sub {
foreach $liste
(@$listes
) {
$liste-
>
yview(@_
);
}
}
);
# Place la barre et les listes
$defil_v-
>
pack
( -
side =>
'left'
, -
fill =>
'y'
);
foreach $liste
(@$listes
) {
$liste-
>
pack
( -
side =>
'left'
);
$liste-
>
insert( 'end'
, "un"
, "deux"
, "trois"
, "quatre"
, "cinq"
, "six"
, "sept"
, "huit"
, "neuf"
, "dix"
, "onze"
);
}
MainLoop;
Pour connecter plusieurs widgets à une seule barre de défilement, on utilise d'abord la méthode Scrollbar pour créer la barre. Puis, on la configure afin qu'elle appelle yview pour chacune des listes que nous voulons faire défiler (ces dernières sont stockées dans un tableau anonyme afin que les méthodes puissent facilement y faire référence). Pour vraiment connecter les listes, on configure chacune d'entre elles pour qu'elle appelle une fonction particulière, faisant défiler les trois listes en plus d'ajuster la barre. Normalement, on ne devrait assigner que ['set',\$liste] à -yscrollcommand : au lieu de cela, nous utilisons la fonction de rappel \&
defiler_listes et nous appelons set depuis celle-ci.
VI-E. Essayez et amusez-vous !▲
- Créez deux widgets, de chacun des types de widgets vus ci-dessus, l'un avec Scrolled et l'autre manuellement. Cela vous permettra de savoir quelle est la méthode que vous préférez ;
- créez deux barres de défilement et attachez-les au même widget (l'opposé de notre exemple « Une seule barre/plusieurs widgets ». Créez, par exemple, une liste avec une barre à gauche et une à droite, les deux faisant défiler la liste verticalement.