我在Tkinter框架里有一些小部件,我想在用户点击时删除。有一些标签,每个标签都有一个相应的按钮来删除它。下面是制作框架的代码。
def delFav():
win2 = Tk()
widgets = []
for url in urls:
label = Label(win2, text = url)
button = Button(win2, text = "Delete")
widgets.append({"url" : url, "label" : label, "button" : button})
for w in widgets:
print w["url"], w["label"], w["button"]
w["button"].configure(command = lambda : delete(w["url"], widgets))
w["label"].pack()
w["button"].pack()
删除功能是这样的。
def delete(url, widgets):
for w in widgets:
if w["url"] == url:
print w["label"]
print w["button"]
w["label"].pack_forget()
w["button"].pack_forget()
return
当我想删除一个URL时,我按下相关的按钮,但总是最后一个按钮被删除。例如,这是点击3个按钮中的第2个删除按钮所产生的输出。
entry/13394 .44877224 .44877384
entry/13277 .44877464 .44877544
entry/8166 .44877624 .44877704
.44877624
.44877704
前3行显示的是小组件列表,点击中间的按钮后,我得到的是最后一个按钮和从删除功能中打印出来的标签名称,作为最后两行。
我点击任何按钮,只有最后一个标签和按钮消失。如何纠正?
这就是以前的 "循环中声明的函数绑定过晚 "的问题。
w["button"].configure(command = lambda : delete(w["url"], widgets))
在这一行,命令 delete(w["url"], widgets)
假设 w
最终值为 w
的值,而不是你调用 configure
. 所以点击任何按钮都会删除最后一个标签。
你可以通过传递w作为默认参数来强制lambda "提前绑定"。
w["button"].configure(command = lambda w=w: delete(w["url"], widgets))