You cannot use all three bindings and get the same result1 because the result is dependent on the ordering of the widget bind tags.
Every widget has an ordered set of bind tags. Bindings are actually attached to these tags rather than the actual widget. It just so happens that the first bind tag is the name of the widget.
By default a widget has the following bind tags in the following order:
- the widget itself
- the widget class (internal tk class, not tkinter class)
- the widget toplevel (or root window)
- "all"
When an event occurs on a widget, the following four things happen:
- if the widget has a binding that matches the event, process that binding
- if the widget class has a binding that matches the event, process that binding
- if the widget's toplevel (or root) has a binding that matches the event, process that binding
- if there is a binding on "all", process that event.
At any time, if a binding returns the literal string "break"
, no more bindings will be processed. Without returning "break"
, all four of the event handlers are processed. In the case of your widget binding returning "break"
, the class, toplevel and "all" bindings won't be processed.
In the specific case of binding <Key>
with bind_all
, this is what happens:
- the widget has no binding that matches the event, so nothing is done
- the widget class has a binding, so it is processed. In this case a letter for the key is inserted into the widget
- the widget's toplevel/root has no binding, so nothing is done
- the "all" tag has a binding so it will insert
"a\n"
.
Because the binding for "all"
happens after the binding for the widget class, returning "break"
has no effect, and cannot prevent the default behavior of inserting an "a" in addition to your custom behavior.
Bind tags are a stunningly beautiful way of handling events. I've used at least half a dozen different GUI toolkits in several different languages over the course of many years, and nothing comes close to the power of tk's bind tags mechanism.
1 You actually can get the same behavior for all three by adding or removing bind tags, or changing the order of the bind tags. You do this with the bindtag
method. There is rarely a need to do so, but it is remarkably handy for some special cases.