for循环中的文本绑定

时间:2017-05-19 18:10:31

标签: python python-3.x user-interface tkinter

For循环解析文件并将信息添加到字典中。然后在用户可以单击的“文本”窗口小部件中插入一个链接,并为其提供一个包含字典详细信息的弹出窗口。如果只有一个文件在你身上,但如果u中有多个文件,则tag_bind使用u中的最后一个文件作为popfunc函数,这样可以正常工作。我明白为什么会这样做,但我想不出更好的方法来通过循环来避免这个问题。建议?

def popfunc(event, path, dictionary):
    win = Toplevel()
    txt2 = Text()
    txt2.grid()
    for key, value in dictionary.items():
        if path == key:
            txt2.insert('end', value)

txt = Text()
txt.grid()
u = <list of files>
for i in u:
   txt.tag_bind('pop', '<Button-1>', lambda event: popfunc(event, i, dictionary))
   with open(i, 'r') as f:
       h = f.readlines()
       for line in h:
           <parse file and add info to dictionary>       
           txt.insert('end', 'User Info: ')
           txt.insert('end', 'Click here to see info', 'pop')

1 个答案:

答案 0 :(得分:1)

你有两个问题。第一个是您为每一行使用相同的标记,因此任何这些行的任何单击都将触发您最后一次绑定。

一个简单的解决方案是为每一行提供一个唯一的标记。例如:

for i in u:
    tag = "pop-%s" % i
    ...
    txt.insert('end', 'Click here to see info', tag)

第二个问题是您的绑定将始终使用i的最后一个值。您需要创建一个闭包以将循环中的当前值附加到绑定。最常见的方法是通过lambda的默认参数:

txt.tag_bind('pop', '<Button-1>', lambda event, item=i: popfunc(event, item, dictionary))

您不必使用其他变量名称(item vs i)。例如,这也适用:

txt.tag_bind('pop', '<Button-1>', lambda event, i=i: popfunc(event, i, dictionary))

就我个人而言,我发现不熟悉lambdas的人会因此而感到困惑,所以我喜欢使用不同的名字。