【问题标题】:unite python "for" with tkinter [duplicate]将python“for”与tkinter联合起来[重复]
【发布时间】:2017-08-28 11:12:23
【问题描述】:

我有一个简单的问题。我有一个值列表 (l1),我希望它为列表中的每个值生成 Button,从而为 textvariable (tkvar) 添加值。程序制作按钮,但每个按钮都添加列表的最后一个值。如何使该按钮根据他的位置为“tkvar”添加正确的值?

import Tkinter as Tk
main=Tk.Tk()
l1=["A", "B", "C"]
def phase(): 
    for i in l1:
        Tk.Button(main, text = i, command=lambda: read(i)).pack(side="left")
    e=Tk.Entry(main, textvariable=tkvar)
    e.pack()
    return
def read(q,*par):
    tkvar.set(q)
tkvar=Tk.StringVar()
phase()
main.mainloop()

【问题讨论】:

    标签: python python-2.7 for-loop tkinter


    【解决方案1】:
    for i in l1:
        Tk.Button(main, text = i, command=lambda: read(i)).pack(side="left")
    

    您已经运行了一个循环,您可以在其中使用lambda 创建闭包。这些调用中的每一个调用read(i) 时,i 来自phase 的范围,在 for 循环完成很久之后。

    一种解决方法是获取 i 的值并将其作为默认参数存储在 lambda 中:

    lambda i=i: read(i)
    

    这存储了在函数的默认参数中创建 lambda 时 i 的值。我们可以检查函数的不同行为:

    >>> i=123
    >>> lambda i=i: read(i)
    <function <lambda> at 0x7f8d714b8a28>
    >>> dis.dis(_)
      1           0 LOAD_GLOBAL              0 (read)
                  3 LOAD_FAST                0 (i)
                  6 CALL_FUNCTION            1
                  9 RETURN_VALUE
    >>> lambda: read(i)
    <function <lambda> at 0x7f8d714b8aa0>
    >>> dis.dis(_)
      1           0 LOAD_GLOBAL              0 (read)
                  3 LOAD_GLOBAL              1 (i)
                  6 CALL_FUNCTION            1
                  9 RETURN_VALUE
    

    部分应用程序可能会更简洁,完全替换 lambda:

    from functools import partial
    command = partial(read, i)
    

    在这种情况下,readi 都被查找以进行 partial 调用,并且不会有全局加载,因此不会保持 phase 的局部变量处于活动状态。

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2021-09-28
      • 2012-08-18
      • 1970-01-01
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 2015-08-12
      相关资源
      最近更新 更多