Tkinter: Distinguishing different

Jeff Epler jepler at unpythonic.net
Sat Dec 28 13:26:13 EST 2002


On Sat, Dec 28, 2002 at 12:40:07AM +0000, Tim Daneliuk wrote:
> I have an existing program that binds a feature to:
> 
>         <Control-Double-ButtonRelease3>
> 
> I now want to add a new feature which binds to:
> 
>         <ButtonRelease-3>
> 
> The problem is that the handler for the second is always called even
> when I am pressing the key combination for the first. Obviously, the
> "ButtonRelease-2" is checked by the message dispatcher before the
> Control ... combination is checked.

What you describe is in direct conflict with Tk's documentation, or else
you're not describing it clearly enough.  Assuming both bindings are made
on the same widget or tag, the more specific binding will be the one used.
So if you have a binding for <X> and <Control-X>, the first binding will
fire for the event <X>, and the event <Alt-X>, and the second binding
will fire for <Control-X> and <Alt-Control-X>.

On the other hand, in the presence of only a binding for <X> on a given
widget/tag, it will fire for all variations of <X>.

If you place one binding on a particular Button, and the other binding on
all Buttons using bind_class(), then two bindings will have the opportunity
to fire.  You can return "break" (the string) from a Python binding to stop
this behavior.

I've included the actual documentation from Tk below (a portion of the
manpage bind(n)).  This is from version 8.3, but I don't believe the
handling of multiple matching bindings has changed substantially in any
8.x version of Tk.

Jeff

[...]
MULTIPLE MATCHES
       It  is  possible  for  several bindings to match a given X
       event.  If the  bindings  are  associated  with  different
       tag's,  then  each  of  the  bindings will be executed, in
       order.  By default, a binding for the widget will be  exe­
       cuted  first,  followed  by a class binding, a binding for
       its toplevel, and an all binding.   The  bindtags  command
       may  be  used to change this order for a particular window
       or to associate additional binding tags with the window.

       The continue and break commands may be used inside a bind­
       ing  script to control the processing of matching scripts.
       If continue is invoked, then the current binding script is
       terminated but Tk will continue processing binding scripts
       associated with other tag's.   If  the  break  command  is
       invoked  within  a binding script, then that script termi­
       nates and no other scripts will be invoked for the  event.

       If  more  than  one binding matches a particular event and
       they have the same tag, then the most specific binding  is
       chosen  and  its script is evaluated.  The following tests
       are applied, in  order,  to  determine  which  of  several
       matching  sequences is more specific: (a) an event pattern
       that specifies a specific button or key is  more  specific
       than  one that doesn't; (b) a longer sequence (in terms of
       number of events matched) is more specific than a  shorter
       sequence;  (c)  if  the modifiers specified in one pattern
       are a subset of the modifiers in another pattern, then the
       pattern  with more modifiers is more specific.  (d) a vir­
       tual event whose physical pattern matches the sequence  is
       less  specific  than the same physical pattern that is not
       associated with a virtual event.   (e)  given  a  sequence
       that  matches  two or more virtual events, one of the vir­
       tual events will be chosen, but the order is undefined.

       If the matching sequences contain  more  than  one  event,
       then  tests  (c)-(e)  are  applied  in order from the most
       recent event to the least recent event in  the  sequences.
       If  these  tests fail to determine a winner, then the most
       recently registered sequence is the winner.

       If there are two (or more) virtual events  that  are  both
       triggered  by the same sequence, and both of those virtual
       events are bound to the same window tag, then only one  of
       the  virtual  events  will  be  triggered,  and it will be
       picked at random:
              event add <<Paste>> <Control-y>
              event add <<Paste>> <Button-2>
              event add <<Scroll>> <Button-2>
              bind Entry <<Paste>> {puts Paste}
              bind Entry <<Scroll>> {puts Scroll}
       If the user types Control-y, the <<Paste>> binding will be
       invoked,  but  if  the  user  presses button 2 then one of
       either the <<Paste>> or the <<Scroll>>  bindings  will  be
       invoked,  but exactly which one gets invoked is undefined.

       If an X event does not match any of the existing bindings,
       then  the  event is ignored.  An unbound event is not con­
       sidered to be an error.


MULTI-EVENT SEQUENCES AND IGNORED EVENTS
       When a sequence specified in a bind command contains  more
       than  one event pattern, then its script is executed when­
       ever the recent events (leading up to  and  including  the
       current  event) match the given sequence.  This means, for
       example, that  if  button  1  is  clicked  repeatedly  the
       sequence  <Double-ButtonPress-1>  will  match  each button
       press but the first.  If extraneous events that would pre­
       vent a match occur in the middle of an event sequence then
       the extraneous events are ignored unless they are KeyPress
       or   ButtonPress  events.   For  example,  <Double-Button­
       Press-1> will match a sequence of  presses  of  button  1,
       even though there will be ButtonRelease events (and possi­
       bly Motion events) between the ButtonPress  events.   Fur­
       thermore,  a  KeyPress event may be preceded by any number
       of other KeyPress events for  modifier  keys  without  the
       modifier  keys preventing a match.  For example, the event
       sequence aB will match a press of the a key, a release  of
       the  a key, a press of the Shift key, and a press of the b
       key:  the press of Shift is ignored because it is a  modi­
       fier  key.   Finally,  if several Motion events occur in a
       row, only the last one is used for  purposes  of  matching
       binding sequences.




More information about the Python-list mailing list