pythontkinter

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.


Solution

  • 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