1

I have a Tkinter canvas and bound a mouse button press event to it.

I was wondering if I could figure out on what specific shape a user clicked when bound to a canvas:

def callback(event): pass canvas = Canvas(root, width=100, height=100) canvas.create_rectangle(10,50,40,90, tags="tile") canvas.bind("<Button-1>", callback) 

I know I can bind it to the the rectangle, the problem is that there might be a another shape overlaying the rectangle and then the click event doesn't work anymore.

I was thinking of using the find_overlapping method:

def callback(event): canvas.find_overlapping(event.x, event.y,event.x, event.y) 

but was wondering if there is an easier way?

3
  • Does the suggested method work? It seems find by me. Also maybe find_enclosed Commented Jul 26, 2022 at 23:33
  • find_enclosed does not work bc the shape has to be inside the rectangle created by the points. find_overlapping works, i was hoping there is an easier way though. Commented Jul 27, 2022 at 0:02
  • 1
    See also How do I get the id of the widget that invoked an event in TKinter?. Even though the rectangle isn't a widget, the fundamental approach is the same - Tkinter offers the magic name 'current' for both cases. Commented Nov 11, 2024 at 17:29

1 Answer 1

1

You can use the special item tag current to refer to the object under the cursor. According to the official documentation:

The tag current is managed automatically by Tk; it applies to the current item, which is the topmost item whose drawn area covers the position of the mouse cursor (different item types interpret this in varying ways; see the individual item type documentation for details). If the mouse is not in the canvas widget or is not over an item, then no item has the current tag.

Here is a simple example. It draws a bunch of colored rectangles, and then sets the color to white when you click on them.

import tkinter as tk import random def click_handler(event): event.widget.itemconfigure("current", fill="white") root = tk.Tk() canvas = tk.Canvas(root, bg="bisque", width=400, height=400) canvas.pack(fill="both", expand=True) canvas.bind("<1>", click_handler) for i in range(100): x = random.randint(0, 350) y = random.randint(0, 350) color = random.choice(("red", "orange", "green", "blue")) width = random.randint(25, 50) height = random.randint(25, 50) canvas.create_rectangle(x, y, x+width, y+height, fill=color) root.mainloop() 

screenshot

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.