python tkinter tag_bind 无法在循环内工作

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 is 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 is not working as above
for 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()

在 windows 上使用 python 3.4,它在使用循环时仅突出显示最后一个对象。但是手动(没有像评论部分中使用的那样循环正常工作)...任何解决方案??

当您在 for 循环中执行此操作时,lambda 会捕获最后读取的对象的最后一个 ID。作为证据,如果您以相反的顺序遍历对象列表 (for obj in reversed(can_obj):),您会注意到只有最左边的对象按预期运行。

您可以使用辅助函数解决您的问题:

#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
for obj in reversed(can_obj):    
    canv.tag_bind(obj, '<Enter>', first_helper(obj))
    canv.tag_bind(obj, '<Leave>', second_helper(obj))

演示

使用上面的代码会得到你期望的结果:

  1. 将鼠标悬停在第二个对象上:

  2. 将鼠标移动到第一个对象: