python tkinter tag_bind not working inside loop -
from tkinter import * def onobjectclick(event, obj): canv.itemconfig(obj, width=2) def no_onobjectclick(event, obj): canv.itemconfig(obj, width=1) root = tk() canv = canvas(root, width=500, height=500) can_obj = [] w=10 ii=0 while ii < 2: points = [w,100, w+10,0, w+20,100] ln = canv.create_line(points, fill='green') can_obj.append(ln) w+=10 ii+=1 ii=0 ##this part working fine ##canv.tag_bind(can_obj[1], '<enter>', lambda event : onobjectclick(event, can_obj[1])) ##canv.tag_bind(can_obj[1], '<leave>', lambda event : no_onobjectclick(event, can_obj[1])) ##canv.tag_bind(can_obj[0], '<enter>', lambda event : onobjectclick(event, can_obj[0])) ##canv.tag_bind(can_obj[0], '<leave>', lambda event : no_onobjectclick(event, can_obj[0])) #this not working above obj in can_obj: canv.tag_bind(obj, '<enter>', lambda event : onobjectclick(event, obj)) canv.tag_bind(obj, '<leave>', lambda event : no_onobjectclick(event, obj)) canv.pack() #root.mainloop()
with python 3.4 on windows, highlights last object while use loop. manually(without loop work used in comment section)... solution??
when inside loop, lambda captures last id of last object read. proof, if loop on list of objects in reverse order(for obj in reversed(can_obj):
) notice left object acting expected.
you can resolve problem using helper functions:
#implementing 2 helpers def first_helper(obj): return lambda event:onobjectclick(event,obj) def second_helper(obj): return lambda event:no_onobjectclick(event,obj) #using our helpers obj in reversed(can_obj): canv.tag_bind(obj, '<enter>', first_helper(obj)) canv.tag_bind(obj, '<leave>', second_helper(obj))
demo
using above code lead result expecting: