Why has the tkinter key-event <Tab> a higher priority than the tkinter key-event <key>?

I am writing an editor (using the tkinter text widget), which replaces tab-characters (inserted by the user) on the fly by 4 blanks.
The replacement is done by a binding to the tabulator-key-event ("Tab"), which inserts 4 blanks and returns with "break". Returning with "break" prevents the tabulator-character from being inserted. This works fine.
Additionally I need a second binding to any key-event ("Key", for syntax highlighting and similar stuff). So I implemented a second binding to "Key". This also works fine.

As I found, the binding of has a higher priority as the binding of :
Whenever the tab-key is pressed, only the tab-event gets active but never the key-event.

Why is that?
Is there any priority order defined for events?

This is my example code:

import tkinter as tk

def key_event():
    print("Key")

def tab_event(text):
    print("Tab")
    text.insert("insert", "    ")
    return("break")

root = tk.Tk()

text = tk.Text(root, height=8, width=20)
text.grid()
text.bind("<Tab>", lambda event : tab_event(text))
text.bind("<Key>", lambda event : key_event())

root.mainloop()

>Solution :

According to the documentation, the more specific binding is chosen over the other. A simple but effective way around this is to use a broad binding like '<Key>' and delegate the event accordingly by it’s keysym, that you can access by event.keysym.

As example:

import tkinter as tk

def key_event(event):
    if event.keysym == 'Tab':
        text.insert("insert", " "*4)
        return 'break'

root = tk.Tk()
text = tk.Text(root, height=8, width=20)
text.grid()
text.bind("<Key>", key_event)

root.mainloop()

Leave a Reply