Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I bind a key-event to a Python tkinter canvas item?

I want to bind a key event to a Python tkinter canvas item, for example to a rectangle. I am able to bind a key to the canvas itself (see example code, key "a", "b", "c"), but not to a canvas-item as a rectangle (see example code, key "r", "s", "t"). What am I doing wrong?

I tried it in this way, but I get only a reaction, when "a", "b" or "c" is pressed at any place in the canvas, but never when "r", "s" or "t" is pressed over the rectangle:

import tkinter as tk

def canvas_hit(event):
    print("Canvas Hit")

def rectangle_hit(event):
    print("Rectangle Hit")

root = tk.Tk()

canvas_id = tk.Canvas(root, height=100, width=200)
rectangle = canvas_id.create_rectangle(20,20,50,50, fill="red")
canvas_id.grid()

canvas_id.bind_all("a"           , canvas_hit)
canvas_id.bind_all("<b>"         , canvas_hit)
canvas_id.bind_all("<KeyPress-c>", canvas_hit)
canvas_id.tag_bind(rectangle, "r"           , rectangle_hit)
canvas_id.tag_bind(rectangle, "<s>"         , rectangle_hit)
canvas_id.tag_bind(rectangle, "<KeyPress-t>", rectangle_hit)

root.mainloop()

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It’s not possible to bind keyboard events to canvas objects, except for text items. From the canonical documentation for the focus method of the canvas:

"Set the keyboard focus for the canvas widget to the item given by tagOrId. If tagOrId refers to several items, then the focus is set to the first such item in the display list that supports the insertion cursor. If tagOrId does not refer to any items, or if none of them support the insertion cursor, then the focus is not changed."

The only canvas item that supports the insertion cursor is text.

The most common solution is to bind to the canvas (not using bind_all but to the actual canvas), and then also giving the canvas the keyboard focus.

canvas_id.bind("r", rectangle_hit)
canvas.focus_set()

It is then up to you to decide which canvas item should receive the event. For example, you can use the tag "current" to reference the object under the cursor. Or, you could implement your own concept of focus for a canvas object.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading