我不明白为什么这一小段代码适用于绿点(当我单击它时,显示的标签是可以的(,但对于红色的标签则完全不行(标签总是相同的,尽管循环:最新的一个(。
这是一个错误吗?还是我错过了什么?
import tkinter as tk
def show(event, p, tag):
print(f"{p=}n{tag=}")
centers = [[50, 50], [90, 50]]
root = tk.Tk()
canvas = tk.Canvas()
canvas.grid(row=0, column=0, sticky='news')
p1 = canvas.create_oval(20,10,30,20, fill='green',tags=('point_green_1', 'draw'))
p2 = canvas.create_oval(50,10,60,20, fill='green',tags=('point_green_2', 'draw'))
canvas.tag_bind(p1, '<Button-1>', lambda event: show(event, p1, ('point_green_1', 'draw')))
canvas.tag_bind(p2, '<Button-1>', lambda event: show(event, p2, ('point_green_2', 'draw')))
for idx, center in enumerate(centers):
tag= f'point_{idx}'
p=canvas.create_oval(center[0] - 5, center[1] - 5, center[0] + 5, center[1] + 5, fill='red',
tags=(tag, 'draw'))
canvas.tag_bind(p, '<Button-1>', lambda event: show(event, p, tag))
root.mainloop()
按如下所示更改代码
import tkinter as tk
def show(event, p, tag):
print(f"{p}n{tag}")
centers = [[50, 50], [90, 50]]
root = tk.Tk()
canvas = tk.Canvas()
canvas.grid(row=0, column=0, sticky='news')
p1 = canvas.create_oval(20,10,30,20, fill='green',tags=('point_green_1', 'draw'))
p2 = canvas.create_oval(50,10,60,20, fill='green',tags=('point_green_2', 'draw'))
canvas.tag_bind(p1, '<Button-1>', lambda event: show(event, p1, ('point_green_1', 'draw')))
canvas.tag_bind(p2, '<Button-1>', lambda event: show(event, p2, ('point_green_2', 'draw')))
for idx, center in enumerate(centers):
tag= f'point_{idx}'
p=canvas.create_oval(center[0] - 5, center[1] - 5, center[0] + 5, center[1] + 5, fill='red', tags=(tag, 'draw'))
canvas.tag_bind(p, '<Button-1>', lambda event, p=p, tag=tag: show(event, p, tag))
root.mainloop()
问题出在绑定红色按钮事件canvas.tag_bind(p, '<Button-1>', lambda event: show(event, p, tag))
的行中
在 lambda 中,您还必须传递参数p=p, tag=tag
,如果不在回调中传递tag
的引用并传递for loop
中使用的p
变量。这将导致每次更改该变量时,它们也会在回调函数中更改,并且它将生成您所看到的"error"
。相反,如果您在labmda
中设置变量,您将在回调处传递不会再次触及的新变量。