Python Tkinter Canvas fail to bind keyboard

I've been running a small script like this

from Tkinter import *
root = Tk()
def callback(event):
    print "callback"
w = Canvas(root, width=300, height=300)
w.bind("<Key>", callback)
w.pack()
root.mainloop()

However, the keyboard event is not handled in my situation (I use python 2.7 on window 7)

If I use

w.bind("<Button-1>", callback)

Things work fine.

So, this really puzzles me. Please anyone tell me why this's happening, thanks in advance.


Key bindings only fire when the widget with the keyboard focus gets a key event. The canvas by default does not get keyboard focus. You can give it focus with the focus_set method. Typically you would do this in a binding on the mouse button.

Add the following binding to your code, then click in the canvas and your key bindings will start to work:

w.bind("<1>", lambda event: w.focus_set())

To avoid the "clicking on the canvas to activate the key bindings", I found simpler code at the following site:

http://ubuntuforums.org/showthread.php?t=1378609

He is attempting to bind a frame, but I implemented it in my own code and the canvas widget works as well. Your code will look like the following:

w.focus_set()
w.bind(<Key>, callback)

There is a handy event in tkinter called "Enter", that tracks when the mouse enters a widget. If you bind it to the canvas, and in the binding's callback for that event you canvas.focus_set, then whenever the mouse is on the canvas you will have focus, and thus the keyboard bindings will work.

This will work even if the canvas looses focus (say through entering text in another widget), because when the mouse enters again the canvas, it will regain focus.