(正如’家庭作业’标签所示,这是计算机科学大项目的一部分.)
我正在写一个危险的!使用tkinter在Python中进行模拟,我在按钮中使用lambda函数时遇到了很大的问题.假设root = Tk()和类别是一个列表.
# Variable to keep the buttons
root._buttons = {}
# Display headers on top of page
for i in range(5):
# Get category name for display in main window
name = categories[i]
b = Label(root, text=fill(name.upper(), 10), width=18, height=3,\
bg="darkblue", fg="white", font=("Helvetica bold", "", 11))
b.grid(row=0, column=i)
# Create list of buttons in that variable (root._buttons)
btnlist = [None]*5
# Display individual questions
for j in range(5):
# Make a button for the question
b = Button(root, text="$" + str(200 * (j+1)), width=8, height=1,
bg="darkblue", fg="orange", font=("Impact", "", 30))
b.cat = name
b.value = 200 * (j + 1)
b.sel = lambda: select(b.cat, b.value)
# Add callback event to button
print(b.cat, b.value, b.sel)
b.config(command=b.sel)
# Add button to window
b.grid(row=j+1, column=i)
# Append to list
btnlist[j] = b
root._buttons[categories[i]] = btnlist
它位于lambda:select(b.cat,b.value),问题似乎发生,因为当我点击电路板上的任何按钮时,它总是转到电路板上的最后一个按钮.我尝试过其他方法,不幸的是都使用lambda,我没有看到任何不涉及lambda的方法.
解决方法:
更改
lambda: select(b.cat, b.value)
至
lambda b = b: select(b.cat, b.value)
在原始代码中,b不是lambda的局部变量;它在封闭范围内找到.完成for循环后,b保留最后一个值.这就是为什么lambda函数都使用最后一个按钮.
如果将lambda定义为使用默认值获取一个参数,则在定义lambda时确定(并修复)默认值.现在b是lambda的局部变量,并且当没有参数调用lambda时,Python将b设置为默认值,根据需要愉快地设置为各种不同的按钮.
标签:python,lambda,tkinter
来源: https://codeday.me/bug/20190725/1538536.html