Tk::bind - Invoquer des callbacks à partir d'événements X
Récupérer des liaisons :
$widget->bind
$widget->bind(tag)
$widget->bind(sequence)
$widget->bind(tag,sequence)
Créer et détruire des liaisons :
$widget->bind(sequence,callback)
$widget->bind(tag,sequence,callback)
La méthode bind associe les callbacks avec les événements X. Si callback
est spécifié, bind fera en sorte que callback sera évalué chaque fois
que le ou les événements décrits par sequence se produiront dans la (ou
les) fenêtre(s)
identifiée(s)
par $widget ou tag. Si callback est une
chaîne vide alors la liaison courante pour sequence est détruite, laissant
sequence sans lien. Dans tous les cas où un argument callback est
fourni, bind renvoie une chaîne vide.
Si sequence est spécifiée sans callback, alors le callback lié actuellement à sequence est renvoyé, ou bien undef s'il n'y a pas de liaison pour sequence. Si sequence et callback ne sont pas spécifiées, alors la valeur de retour est une liste dont les éléments sont toutes les séquences pour lesquelles il existe des liaisons pour tag.
Si aucun tag n'est spécifié alors bind se réfère à $widget. Si tag est spécifié il s'agit typiquement d'un nom de classe et bind se réfère à toutes les instances de classe associées à $widget sur MainWindow. (tag peut être un autre ``objet widget'' mais cette pratique est désapprouvée). La méthode de Perl ref($object) est là pour retrouver le nom de classe de n'importe quel objet. Chaque fenêtre a une liste de tags associée, et une liaison s'applique à une fenêtre particulière si ses tag font partie de ceux spécifiés pour la fenêtre. Bien que la méthode bindtags puisse être utilisée pour assigner un ensemble arbitraire de tags de liaison à une fenêtre, les tags de liaison par défaut fournissent le comportement suivant :
Si un tag est le nom d'une fenêtre interne la liaison s'applique à cette fenêtre ;
Si le tag est le nom d'une fenêtre toplevel la liaison s'applique à la fenêtre toplevel et à toutes ses fenêtres internes ;
Si le tag est le nom d'une classe de widgets, comme Tk::Button, la liaison s'applique à tous les widgets de cette classe ;
Si tag a la valeur all, la liaison s'applique à toutes les fenêtres descendantes de la MainWindow de l'application.
L'argument sequence spécifie une séquence de un ou plusieurs motifs d'événement, avec des caractères 'espace' optionnels entre les motifs. Chaque motif d'événement peut prendre trois formes. Le cas le plus simple est un simple caractère ASCII, tel que a ou [. Ce caractère ne peut pas être l'espace ni le caractère <. Cette forme de motif relie un événement KeyPress à ce caractère particulier. La deuxième forme est plus longue mais plus générale. Elle a la syntaxe suivante :
'<modificateur-modificateur-type-detail>'
Le motif d'événement est encadré par '<' et '>', et doit normalement être entre quotes, car '<' et '>' sont des caractères spéciaux de perl. Entre '<' et '>' on trouve zéro modificateurs ou davantage, un type d'événement, et une information supplémentaire (detail) qui identifie un bouton particulier ou un code symbolique de touche. N'importe quel champ peut être omis, pouvu qu'au moins type ou detail soit présent. Les champs doivent être séparés par des espaces ou des tirets.
La troisième forme de motif est utilisée pour spécifier un événement virtuel nommé défini par l'utilisateur ; voir Tk::event pour les détails. Il a la syntaxe suivante :
<<name>>
Le motif d'événement virtuel est écrit entre '<<' et '>>'. Entre '<<' et '>>' se trouve le nom (défini par l'utilisateur) de l'événement virtuel. Les modificateurs, tels que Shift ou Control, ne doivent pas être combinés avec un événement virtuel pour le modifier. Les liaisons sur un événement virtuel doivent être créées avant que l'événement virtuel soit défini, et si la définition de l'événement virtuel change dynamiquement, toutes les fenêtres liées à cet événement virtuel répondent immédiatement à la nouvelle définition.
Les modificateurs sont énumérés ci-après :
Control Mod2, M2 Shift Mod3, M3 Lock Mod4, M4 Button1, B1 Mod5, M5 Button2, B2 Meta, M Button3, B3 Alt Button4, B4 Double Button5, B5 Triple Mod1, M1 Quadruple
Lorsque plusieurs valeurs sont listées, séparées par une virgule, les valeurs sont équivalentes. La plupart des modificateurs ont une signification X évidente. Par exemple, Button1 demande à ce que le bouton 1 soit enfoncé pour que l'événement se produise. Pour qu'une liaison corresponde à un événement donné, les modificateurs de l'événement doivent inclure tous ceux spécifiés dans le motif d'événement. Un événement peut contenir des modificateurs additionnels non spécifiés dans la liaison. Par exemple, si le bouton 1 est pressé alors que les touches shift et control sont enfoncées, le motif <Control-Button-1> correspondra à l'événement, mais <Mod1-Button-1> ne correspondra pas. Si aucun modificateur n'est spécifié, alors n'importe quelle combinaison de modificateurs peut être présente dans l'événement.
Meta et M se réfèrent à n'importe quel modificateur depuis M1 jusqu'à
M5, associé à une (ou plusieurs) touche(s)
meta du clavier (codes
symboliques de touche Meta_R et Meta_L). S'il n'y a pas de touche meta,
ou si elles ne sont pas associées à un modificateur, Meta et M ne
correspondront à aucun événement. De manière similaire, le modificateur Alt
se réfère à tout modificateur associé à la touche alt du clavier (codes
symboliques de touche Alt_L and Alt_R).
Les modificateurs Double, Triple et Quadruple sont une commodité pour spécifier les double click souris ainsi que d'autre événements répétés. Ils font en sorte qu'un motif d'événement doit être répété 2,3 ou 4 fois, et imposent aussi une contrainte de temps et d'espace dans le séquence : pour qu'une séquence d'événements correspondent à un motif Double, Triple ou Quadruple, tous les événements doivent être proches dans le temps et sans déplacement excessif de la souris entre eux. Par exemple, <Double-Button-1> est équivalent à <Button-1><Button-1> avec une contrainte supplémentaire de temps et d'espace.
Le champ type peut être l'un quelconque des types d'événement X standard, avec quelques abréviations supplémentaires. Ci-dessous une liste de tous le types valides ; lorsque deux noms apparaissent ensemble, séparés par une virgule, ils sont synonymes.
Activate Destroy Map ButtonPress, Button Enter MapRequest ButtonRelease Expose Motion Circulate FocusIn MouseWheel CirculateRequest FocusOut Property Colormap Gravity Reparent Configure KeyPress, Key ResizeRequest ConfigureRequest KeyRelease Unmap Create Leave Visibility Deactivate
La plupart de ces événements ont les mêmes champs et signification que les événements du système de fenêtre X. Vous trouverez une description plus détaillée de ces événements dans tous les livres de programmation X Window. Deux de ces événements représentent une extension du système d'événement X afin de répondre aux fonctionnalités des plate-formes Macintosh et Windows. Voici quelques détails supplémentaires sur ces événements. Il s'agit de :
Activate Deactivate
Ces deux événements sont envoyés à toutes les fenêtres filles d'une toplevel lorsque leur état change. Outre la notion de ``de fenêtre ayant le focus'', les plate-formes Macintosh et Windows ont la notion de ``fenêtre active'' (qui a, le plus souvent, le focus, mais ce n'est pas requis). Sur le Macintosh, les widgets de la fenêtre active ont une apparence différente des widgets des fenêtres désactivées. L'événement Activate est envoyé à toute fenêtre fille d'un toplevel lorsque son état passe d'inactif à actif. De la même manière, l'événement Deactivate est envoyé lorsque la fenêtre passe de l'état activée à l'état désactivée. [There are no use- ful percent substitutions you would make when binding to these events.]
MouseWheel
Les souris des plate-formes Windows comportent souvent une roulette utilisée pour faire défiler les documents sans utiliser les barres de défilement. Lorsqu'on utilise cette roulette, le système génère des événements MouseWheel que l'application peut utiliser pour faire défiler les documents. Tout comme les événements clavier, cet événement est toujours redirigé vers la fenêtre qui a actuellement le focus. Lorsque vous recevez l'événement vous pouvez utiliser la substitution %D pour obtenir le champ déplacement (delta) de l'événement qui est une valeur entière de la distance dont la roulette de la souris s'est déplacée. La plus petite valeur que le système puisse rapporter est définie par l'OS. Sur les machines Windows 95 & 98 cette valeur doit être au moins de 120 avant qu'elle soit rapportée. Toutefois, des périphériques de plus haute résolution seront sans doute disponibles dans le futur. Le signe de la valeur détermine la direction dans laquelle votre widget doit se déplacer. Les valeurs positives sont associées à des déplacements vers le haut et les valeurs négatives à des déplacements vers le bas.
La dernière partie de la spécification d'un long événement est detail. Dans le cas d'un événement ButtonPress ou ButtonRelease, c'est le numéro du bouton (1-5). Si un numéro de bouton est fourni, seul un événement sur ce bouton particulier correspondra ; si aucun numéro de bouton n'est fourni, un événement correspondra sur n'importe quel bouton. Note : donner un numéro de bouton spécifique est différent de spécifier un modificateur de bouton ; dans le premier cas, on se réfère au bouton pressé ou relâché, dans le deuxième on se réfère à n'importe quel autre bouton qui est encore pressé lorsque survient l'événement en correspondance. Si un numéro de bouton est fourni type peut être omis : ce sera ButtonPress par défaut. Par exemple, le spécificateur <1> est équivalent à <ButtonPress-1>.
Si le type d'événement est KeyPress ou KeyRelease, alors detail doit être spécifié dans la forme d'un code symbolique de touche X. Les codes symboliques de touche sont des spécifications textuelles de touches particulières du clavier ; elles comprennent tous les caractères alphanumériques ASCII (par exemple ``a'' est le code symbolique du caractère ASCII ``a''), plus des descriptions pour les caractères non-alphanumériques (``comma'' est le code symbolique du caractère ``virgule''), plus des descriptions pour toutes les touches non-ASCII du clavier (``Shift_L'' est le code symbolique de la touche shift gauche, et ``F1'' est le code symbolique de la touche de fonction F1, si elle existe). La liste complète des codes symboliques n'est pas présentée ici ; elle est disponible dans d'autres documentations X et peut varier d'un système à l'autre. Si nécessaire, vous pouvez utiliser la notation 'K' décrite ci-dessous pour imprimer le nom de code symbolique d'une touche particulière. Si detail est fourni pour un code symbolique de touche, le champ type peut être omis ; sa valeur par défaut sera KeyPress. Par exemple, <Control-comma> est équivalent à <Control-KeyPress-comma>.
L'argument callback de bind est un callback perl/Tk qui sera exécuté chaque fois que la séquence donnée se présentera. (Voir Tk::callbacks pour une description des formes possibles). callback sera associé à la même MainWindow associée au $widget utilisé pour invoquer la méthode bind, et sera exécuté comme si l'appel provenait de MainLoop. Si callback contient n'importe quel appel Ev(%), chaque ``callback imbriqué'' Ev(%) sera évalué lors de l'occurrence de l'événement pour former les arguments à passer au callback principal. Le remplacement dépend du caractère %, comme défini dans la liste ci-dessous. Sauf indication contraire, la chaîne de remplacement est la valeur numérique (décimale) du champ considéré pour l'événement courant. Perl/Tk a mis un peu en valeur ce mécanisme, en comparaison du mécanisme semblable de Tcl/Tk. Les mises en valeur ne sont pas toutes reflétées dans la liste ci-dessous. Quelques substitutions sont valides uniquement pour certains types d'événement ; si on les utilise pour d'autres types d'événement la valeur substituée est indéfinie (ce qui n'est pas la même chose que undef !).
NotifyAncestor NotifyNonlinearVirtual NotifyDetailNone NotifyPointer NotifyInferior NotifyPointerRoot NotifyNonlinear NotifyVirtual
Pour les événements ConfigureRequest, la chaîne sera l'une parmi :
Above Opposite Below None BottomIf TopIf
Pour les événements autres que ceux-là, la chaîne substituée est indéfinie. (Notez que ceci n'est pas la même chose que la partie Detail de la séquence utilisée pour spécifier l'événement.)
Il peut arriver que plusieurs liaisons correspondent à un événement X donné. Si les liaisons sont associées à différents tags, alors chaque liaison sera exécutée, dans l'ordre. Par défaut, une liaison de classe sera exécutée en premier, suivie par une liaison de widget, une liaison de sa toplevel, et une liaison all. La méthode bindtags peut être utilisée pour changer cet ordre pour une fenêtre particulière ou pour associer des liaisons additionnelles à la fenêtre.
return et Tk->break peuvent être utilisées dans un callback pour contrôler le traitement des callbacks en correspondance. Si return est invoquée, alors le callback courant est terminé mais Tk continuera de traiter les callbacks associés aux autres tag. Si Tk->break est invoqué dans un callback, le callback termine et aucun autre callback ne sera invoqué pour l'événement. (Tk->break est implémentée via die (de perl) avec une valeur spéciale qui est ``interceptée'' par le ``code de collage'' de perl/Tk.)
Si plus d'une liaison correspond à un événement particulier et qu'elles ont le même tag, la liaison la plus spécifique est choisie et son callback évalué. Les tests suivants sont appliqués, dans l'ordre, pour déterminer quelle est la séquence de correspondance la plus spécifique :
Si les séquences en correspondance contiennent plus d'un événement, les tests (c)-(e) seront appliqués dans l'ordre, du plus récent au moins récent des événements des séquences. Si ces tests ne permettent pas de désigner un vainqueur, la séquence enregistrée le plus récemment sera choisie.
S'il existe deux événements virtuels (ou plus) déclenchés par la même séquence, et que ces événements virtuels sont lié au même tag de fenêtre, seulement un des événements virtuels sera déclenché, aléatoirement :
$widget->eventAdd('<<Paste>>' => '<Control-y>'); $widget->eventAdd('<<Paste>>' => '<Button-2>'); $widget->eventAdd('<<Scroll>>' => '<Button-2>'); $widget->bind('Tk::Entry','<<Paste>>',sub { print 'Paste'}); $widget->bind('Tk::Entry','<<Scroll>>', sub {print 'Scroll'});
Si l'utilisateur frappe Control-y, la liaison <<Paste>> sera invoquée, mais si l'utilisateur presse le bouton 2 alors l'une des deux liaisons <<Paste>> ou <<Scroll>> sera invoquée, sans qu'on puisse savoir laquelle.
Si un événement X ne correspond à aucune liaison existante, l'événement est ignoré. Un événement non lié n'est pas considéré comme étant une erreur.
Lorsqu'une sequence spécifiée dans une méthode bind contient plus d'un motif d'événement, son callback est exécuté même si les événements récents (jusqu'à l'événement courant et y compris ce dernier) correspondent à la séquence donnée. Cela signifie, par exemple, que si le button 1 est clické de façon répétitive la séquence <Double-ButtonPress-1> ne correspondra que la première fois. Si des événements étrangers capables de prévenir une correspondance surgissent au milieu d'une séquence d'événements ils sont alors ignorés sauf si ce sont ces événements KeyPress ou ButtonPress. Par exemple, <Double-ButtonPress-1> correspondra à une séquence de bouton 1 pressé plusieurs fois, même s'il existe des événements ButtonRelease (et peut-être aussi des événemenst Motion) entre les événements ButtonPress. De plus, un événement KeyPress peut être précédé par n'importe quel nombre d'autres événements KeyPress pour les touches de modification sans que les touches de modification annulent la correspondance. Par exemple, la séquence d'événement aB correspondra à un KeyPress de la touche a, un Keyrelease de la touche a, l'appui de la touche Shift et un appui de la touche b : presser sur Shift est ignoré parce qu'il s'agit d'une touche modificatrice. Finalement, si plusieurs événements Motion arrivent à la suite les uns de autres, seul le dernier sera considéré pour établir la correspondance des séquences de liaison.
Si une erreur se produit lorsqu'on exécute le calback d'une liaison le mécanisme Tk::Error est utilisé pour rapporter l'erreur. Le mécanisme Tk::Error sera exécuté au même niveau d'appel, et associé avec la même MainWindow qui a invoqué le callback.
Notez que pour le widget Canvas, l'appel de bind doit être pleinement qualifié. Ceci parce qu'il existe toujours une méthode de liaison pour le widget Canvas, qui lie individuellement chaque tag du canevas.
$canvas->Tk::bind
Tk::Error Tk::callbacks Tk::bindtags
Event, binding
Jean-Pierre Vidal jeanpierre.vidal@free.fr
Aucune relecture pour le moment.