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))
演示
使用上面的代码会得到你期望的结果:
将鼠标悬停在第二个对象上:
将鼠标移动到第一个对象:
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))
演示
使用上面的代码会得到你期望的结果:
将鼠标悬停在第二个对象上:
将鼠标移动到第一个对象: