Python Tkinter:在for循环中使用标签绑定函数

时间:2015-04-18 08:02:00

标签: python python-3.x tkinter label

我正在for loop使用tkinter动态创建标签。我不知道将创建多少个标签,但是在点击每个标签时,必须使用特定参数调用特定函数。

为此,我正在使用此代码:

for link in list_of_links:
    link_label = Label(self.video_window, text="Frame "+str(video_number), fg="blue", cursor="hand2")
    link_label.pack()
    link_label.place(x=xcod2, y=ycod2)
    link_label.bind("<1>", lambda x: self.goto_video_link(link))

目前,我正在创建10个标签。问题是,点击十个标签中的任何一个,goto_video_link函数似乎只使用第10个链接。

如果我点击第5个标签,我希望它使用第5个链接。

我该怎么做?

1 个答案:

答案 0 :(得分:3)

Lambda表达式被延迟评估,这意味着self.go_to_link(link)仅在执行时进行评估。在这一刻link包含最后一个链接的值,因此每个按钮都将转到最后一个链接。

您需要在for循环期间强制评估link。这可以通过lambda函数完成,该函数返回另一个具有所需值的lambda函数。我知道这似乎令人困惑,但下面的代码可能会让它更清晰。

eval_link = lambda x: (lambda p: self.go_to_link(x))
for link in list_of_links:
    link_label = Label(self.video_window, text="Frame "+str(video_number), fg="blue", cursor="hand2")
    link_label.pack()
    link_label.place(x=xcod2, y=ycod2)
    link_label.bind("<1>", eval_link(link))

在这种情况下,为了能够构建内部lambda,有必要评估link。由于它作为参数传递,因此最内层的lambda绑定到本地副本x而不是link,并且因为x是局部变量,所以当函数是调用。