Vertus Vertus - 7 months ago 47
Python Question

Python Tkinter - canvas figure : can't bind different tag to multiple figure?

I try to place different figures on a Tkinter canvas, and for each one, attach a tag and bind an action to do.
As example: I place 4 points on a canvas, I attach them a tag composed with their coordinates, and define an action that display a clicked point coordinates, identified by his tag.

If I print the tag when I affect it, it's okay tags are different, but then when it displays the coordinates, it's always the last added point, it seems that all tags were finally the same... I don't understand :/

from Tkinter import *

points=[(10,10),(60,10),(10,60),(60,60)]

def check(pixel):
print('===========')
print('you clicked on:')
print(pixel)

root = Tk()
canvas = Canvas(root, width=70, height=70)
print('----points list----')
for p in points:
tag="("+str(p[0])+","+str(p[1])+")"
print(tag)
canvas.create_oval(p[0]-2,p[1]-2,p[0]+2,p[1]+2,tags=tag)
canvas.tag_bind(tag, '<ButtonPress-1>', lambda event:check(tag))

canvas.pack()
root.mainloop()


possible output: (I clicked on 3 different points)

----points list----
(10,10)
(60,10)
(10,60)
(60,60)
===========
you clicked on:
(60,60)
===========
you clicked on:
(60,60)
===========
you clicked on:
(60,60)


Any ideas ? Thanks a lot.

Answer

After 3 days on it, I found why, if people get stuck at the same point:

using the command tag_bind like this:

for variable...
    canvas.tag_bind(item_id, '<ButtonPress-1>', lambda event:function(variable))

will never work in a loop because the function will take the global variable 'variable' AFTER the loop has finished = always the last value. you need to define in the command itself your variable:

for variable...
    canvas.tag_bind(item_id, '<ButtonPress-1>', lambda event, var=variable:function(var))

like this your function will get it's own variable for each item, and not one variable for all items