Andrew
Andrew

Reputation: 1025

When a rectangle on a canvas is clicked, how can I get the ID of that rectangle?

I have these set of rectangles drawn on a canvas. They are all bind to Button-1 event. What I like to do is set a variable with an id of a widget that invoke the event. Here's a pseudo code of what I like to do

def clicked(e): #event handler. Binds to rectangle objects
    selected_button = e.widgets.get_id()

P.S : Although I bind the event handler to those rectangles objects only, when I place code e.widget.destroy() inside that handler, the canvas is destroyed as well.

Upvotes: 5

Views: 7034

Answers (1)

FabienAndre
FabienAndre

Reputation: 4604

Executive summary

Since canvas method accept indifferently tags or items id, you can use the compact callback

def autodestroy(event):
    event.widget.delete("current")

Details

Your callback receive a Tkinter event as unique parameter. This parameter is an object from whom you can retrieve stimulated widget, as well as other informations (mouse coordinate or buttons in the case of a mouse event).

def clicked(event):
    canvas = event.widget

To get the clicked canvas item, you can either use the CURRENT1 tag

    rect = canvas.find_withtag("current")[0]

or reproduce picking with find_closest, find_overlapping, find_enclosed ...(copied from effbot.org)

    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    rect = canvas.find_closest(x, y)[0]

Note that find_ family return tuples, that might be empty under some circumstance and you might test emptyness or catch exception.

Then to delete an item of a canvas, you can use canvas.delete method.

    canvas.delete(rect)

Since canvas method accept indifferently tags or items id, you can use a more compact writing:

def autodestroy(event):
    event.widget.delete("current")

1 Tkinter.CURRENT and "current"are equivalent

Upvotes: 7

Related Questions