我正在尝试使用tkinter构建一个小的数字键盘,以便能够在纯触摸屏系统上输入密码。这就是我到目前为止所知道的:
从tkinter导入tkinter导入ttk
def main():
root = tkinter.Tk()
numpad = NumPad(root)
root.mainloop()
btn_list = [
'7', '8', '9',
'4', '5', '6',
'1', '2', '3', '0']
class NumPad(ttk.Frame):
def __init__(self, root):
ttk.Frame.__init__(self, root)
self.grid()
self.numpad_create()
def numpad_create(self):
r = 1
c = 0
for b in btn_list:
cmd= lambda: print(b)
self.b= ttk.Button(self, text=b,width=5,command=cmd).grid(row=r,column=c)
print(b)
c += 1
if c > 4:
c = 0
r += 1
main()如果我启动这个程序,它会把数字b打印到shell中,这样就可以工作了。此外,这些按钮也会根据需要进行显示。但是如果我单击它们,我总是得到0作为shell的输出。我找不到我所做的错误,我想这可能与垃圾收集有关,但我不确定。
有人能帮帮我吗?那就太棒了!
谢谢!
发布于 2013-04-30 01:07:10
您的lambda的cmd在声明lambda本身时没有捕捉到b的值。b的最终状态是0,这就是为什么您的所有按钮最终都会打印b。
发布于 2013-04-30 01:53:28
您的lambda应该像这样指定:
cmd= lambda b=b: print(b)这将把b的当前值绑定为您的lambda中名为b的参数的默认值。如果没有此绑定,lambda将使用按下时的b值,而不是创建时的值。
就我个人而言,我发现在两种上下文中使用相同的变量会让人感到困惑;我个人会这样写它,它在功能上是相同的,但更容易理解:
cmd= lambda button=b: print(button)发布于 2013-04-30 01:12:20
NumPad.numpad_create中的for循环遍历每个按钮编号并将它们存储在self.b中。问题是,每个数字都会覆盖self.b的前一个值,因此实际存储的唯一值是0。tkinter自动垃圾收集没有活动引用的对象。向NumPad添加另一个属性,这是一个列表,并将所有按钮对象放入其中。
@thkang也是对的:我认为有两个独立的bug。请注意,我还没有真正测试过这一点。
https://stackoverflow.com/questions/16284099
复制相似问题