如何为循环中的每个按钮分配一个单独的值?

时间:2019-03-25 15:46:53

标签: python python-3.x loops tkinter

我正在使用for循环,我想将一个单独的参数传递给每个单独的按钮(在tkinter中),这是用于计算器的。但是,我找不到解决方案,为了使问题更清楚,我将显示相关代码:

import tkinter as tk

entry_box = tk.Entry(master,width=35)

def insert_value(value):
    entry_box.insert(0,value)   

buttons = []
for i in range(0,10):
    a = tk.Button(master,text=str(i),command=lambda:insert_value(str(i)))
    buttons.append(a)

注意::我已删除了循环中的.grid()语句,因为它删除了相当大且不必要的代码部分。而且我还希望每个按钮插入其显示的值,以便按钮1可以插入1、2、2等。

传递“ i”以插入值时会出现问题,因为插入到输入框中的值始终为9。我认为这是因为“ i”在循环中始终以9结尾。

但是,我找不到解决方案。我尝试从列表中获取值。我想不出任何其他方式做到这一点(在循环中)。 我知道我可以只写10次语句,但是我很想知道它们是否是解决方案。

TL; DR 传递给插入值的值始终为9。 是否可以使用for循环将每个按钮显示的值(1到9)插入输入框?

不管是对的还是所有的建议都会很有趣并且很高兴看到。谢谢。

2 个答案:

答案 0 :(得分:2)

由于i是一个自由变量,因此直到真正调用回调时才对其求值,而不是在首次定义该函数时进行评估。

一种技巧是将循环索引作为否则未使用的函数参数的默认值进行传递。请注意,您不需要整数 i,只需要 string str(i),因此我们在调用tk.Button之前进行替换。

buttons = []
for i in range(0,10):
    i = str(i)
    a = tk.Button(master,text=i, command=lambda i=i:insert_value(i))
    buttons.append(a)

另一种解决方案是显式定义工厂函数来创建回调。 make_callback与您的lambda表达式创建的函数几乎相同,除了它返回围绕其参数的闭包而不是使用默认参数值。

def make_callback(i):
    return lambda: insert_value(i)

buttons = []
for i in range(0,10):
    i = str(i)
    a = tk.Button(master,text=i, command=make_callback(i))
    buttons.append(a)

实际上,如果您愿意,您可以使用嵌套的lambda表达式“内联” make_callback,尽管出于可读性考虑,我不建议这样做。

buttons = []
for i in range(0,10):
    i = str(i)
    a = tk.Button(master,text=i, command=(lambda x: lambda: insert_value(x))(i))
    buttons.append(a)

答案 1 :(得分:0)

在oo解决方案下面。

FOR