gpt4 book ai didi

python - 通过 Tkinter 中的按钮将参数传递给函数,循环中的奇怪行为

转载 作者:行者123 更新时间:2023-12-01 05:37:44 29 4
gpt4 key购买 nike

我目前正在尝试修复Python书籍“Python下一步”中的一个错误,该错误作者尚未修复并在代码中留下了评论:“稍后修复”

我的第一个解决方案失败了,但第二个解决方案通过删除循环成功了。问题是我无法弄清楚为什么第一个解决方案失败了!

解决方案 1:

当用户使用循环、Button 对象和名为 click 的函数单击 Tkinter 中的计算器中的按钮时,计算器仅从 lambda 参数打印大写 C。代码注释为在我正在谈论的点上,靠近有问题的鳕鱼的 V 形图案。

解决方案 2:

删除生成按钮的循环,并重复对每个按钮进行手动编码!这很有效,正如 Brian kernighan 所建议的:先让它工作,然后再提高效率!

代码:

# myCalculator3_final.py

from Tkinter import *
from decimal import *

# key press function:
def click(key):
display.insert(END, key)


##### main:
window = Tk()
window.title("MyCalculator")

# create top_row frame
top_row = Frame(window)
top_row.grid(row=0, column=0, columnspan=2, sticky=N)

# use Entry widget for an editable display
display = Entry(top_row, width=45, bg="light green")
display.grid()

# create num_pad_frame
num_pad = Frame(window)
num_pad.grid(row=1, column=0, sticky=W)

# This method of passing an argument to click work! Loop removed and buttons hand code
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#-------------------------------------------------------------------------
# create num_pad buttons passing an argument to the command function click
#-------------------------------------------------------------------------
seven = Button(num_pad, text="7", width=5, command=lambda :click("7"))
seven.grid(row=0,column=0)
eight = Button(num_pad, text="8", width=5, command=lambda :click("8"))
eight.grid(row=0,column=1)
nine= Button(num_pad, text="9", width=5, command=lambda :click("9"))
nine.grid(row=0,column=2)
four= Button(num_pad, text="4", width=5, command=lambda :click("4"))
four.grid(row=1,column=0)
five= Button(num_pad, text="5", width=5, command=lambda :click("5"))
five.grid(row=1,column=1)
six= Button(num_pad, text="6", width=5, command=lambda :click("6"))
six.grid(row=1,column=2)
one= Button(num_pad, text="1", width=5, command=lambda :click("1"))
one.grid(row=2,column=0)
two= Button(num_pad, text="2", width=5, command=lambda :click("2"))
two.grid(row=2,column=1)
three= Button(num_pad, text="3", width=5, command=lambda :click("3"))
three.grid(row=2,column=2)
zero= Button(num_pad, text="0", width=5, command=lambda :click("0"))
zero.grid(row=2,column=0)
#---------------------------------------------------------------------------



# calculate the row, column for button

# create operator_frame
operator = Frame(window)
operator.grid(row=1, column=1, sticky=E)

operator_list = [
'*', '/',
'+', '-',
'(', ')',
'C' ]

# The authors code and I have added the same lambda function as above but
#it just prints out capital C
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
r = 0
c = 0
for btn_text in operator_list:
Button(operator, text=btn_text, width=5, command=lambda: click(btn_text)).grid(row=r,column=c)
c = c+1
if c > 1:
c = 0
r = r+1


##### Run mainloop
window.mainloop()

问题:

为什么单击传递参数的 lambda 调用方法在循环中不起作用并且仅显示 C,但如果我删除循环它就可以工作!

最佳答案

在这一行:

Button(operator, text=btn_text, width=5, command=lambda: click(btn_text)).grid(row=r,column=c)

lambda 中的 btn_text 值不会卡住为其当前值。相反,当 btn_text 在循环的下一次迭代中发生变化时,它在 lambda 中求值的值也会发生变化。这意味着您的所有按钮实际上都有一个 click('C') 命令,因为 'C'btn_text 的最终值。

你可以这样做:

command=lambda text=btn_text: click(text)

或者

command=(lambda text: lambda: click(text))(btn_text)

text 将捕获 btn_text 的当前值,并且之后不会更改。您的命令将使用正确的参数进行调用。

关于python - 通过 Tkinter 中的按钮将参数传递给函数,循环中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18510403/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com