绑定方法动态创建标签

时间:2016-10-11 21:51:27

标签: python-3.x tkinter

我有一个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()

被调用的方法将始终相同,但如何识别要生效的标签?

2 个答案:

答案 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的工作原理。 (这是非常受欢迎的问题:))

forlambda。当您声明"lazy"但是当您单击按钮(并执行self.thumb时,它不会从lambda x: self.click(self.thumb)获得值。但是当您单击标签时,lambda循环结束并且for保留最后一个值。

声明self.thumb

时,必须使用此方法获取正确的值
lambda