我有一个Tkinter框架,它实际上显示了一组缩略图,显示在Label小部件中。我需要动态创建标签以适应不同数量的缩略图生成。我有一个生成的文件名列表,可以根据需要创建缩略图,但是当我尝试将函数绑定到每个创建的标签时,它似乎被最后创建的Label / Binding覆盖。结果是只有最终标签的方法绑定到它。
import tkinter as tk
class test(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args)
self.shell = tk.Frame(self)
self.shell.pack()
self.create_widgets()
def create_widgets(self):
'''
Two rows of labels
'''
for row in range(2):
for i in range(5):
text = 'Thumbnail\nrow{}\ncolumn{}'.format(row,i)
self.thumb = tk.Label(self.shell,
text = text)
self.thumb.grid(row = row, column = i, sticky = 'news')
self.thumb.bind("<Button-1>",lambda x: self.click(self.thumb))
def click(self, *args):
#This should affect only the Label that was clicked
print('CLICK!')
app = test()
root = app
root.mainloop()
被调用的方法将始终相同,但如何识别要生效的标签?
答案 0 :(得分:1)
至少有三种解决方案。
第一个是最简单的:函数传递一个事件对象,其中包含对窗口小部件的引用:
systemd[1]: Started web server monitor.
heartbeat.py[26298]: Traceback (most recent call last):
heartbeat.py[26298]: File "/home/user/heartbeat.py", line 2, in <
heartbeat.py[26298]: import requests
heartbeat.py[26298]: ImportError: No module named requests
systemd[1]: heartbeat.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: heartbeat.service: Unit entered failed state.
如果您更喜欢使用lambda,可以将标签本身传递给函数:
label = tk.Label(...)
label.bind("<Button-1>", self.click)
...
def click(self, event):
print("you clicked:", event.widget)
另一种解决方案是保持对列表中每个标签的引用,并将索引传递给函数:
label = tk.Label(...)
label.grid(...)
label.bind("<Button-1>",lambda event, label=label: self.click(label))
答案 1 :(得分:0)
单击标签后,tk将使用v8::ScriptCompiler::Source
运行功能,您可以使用event object
跳过该功能。
你需要
lambda x
然后在lambda event:self.click(event, ...)
中,您可以使用click
来获取点击的小部件。
event.widget
def click(event, ...);
print('Widget text:', event.widget['text'])
中的self.thumb
您遇到问题,因为您不知道self.click(self.thumb)
循环中lambda
的工作原理。 (这是非常受欢迎的问题:))
for
是lambda
。当您声明"lazy"
但是当您单击按钮(并执行self.thumb
时,它不会从lambda x: self.click(self.thumb)
获得值。但是当您单击标签时,lambda
循环结束并且for
保留最后一个值。
声明self.thumb
lambda