2013-04-29 46 views
0

我正尝试使用tkinter构建一个小数字键盘,以便能够在纯触摸系统上输入密码。这是我到目前为止有:从Tkinter的进口TTKtkinter中的小数字键盘

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() 

进口的Tkinter 如果我开始PROGRAMM,它打印的数字B向外壳,使这部作品。此外按钮显示为希望。但是如果我点击它们,我会始终将0作为输出到shell。我找不到我犯的错误,我认为这可能与垃圾收集有关,但我不确定。

有人能帮助我吗?这将是非常棒的!

谢谢!

回答

2

cmd,你的lambda,在lambda本身被声明的时候没有捕获到b的值。 b的最终状态为0,这就是为什么所有按钮最终都会打印b

+0

谢谢,完美的作品! – user2304540 2013-04-29 19:33:02

0

NumPad.numpad_create中的for循环遍历每个按钮编号并将它们存储在self.b中。问题是每个数字都会覆盖之前的值self.b,因此实际存储的唯一值是0。 tkinter自动垃圾收集没有实时参考的对象。将另一个属性添加到NumPad这是一个列表,并将所有按钮对象放入其中。

@thkang也是对的:我认为有两个单独的错误。请注意,我没有真正测试过这个。

2

你拉姆达应该这样指定:

cmd= lambda b=b: print(b) 

这会的b当前值绑定在你的拉姆达命名b参数的默认值。如果没有这种绑定,lambda将在按下时使用b的值,而不是在创建时的值。

就我个人而言,我发现在上下文中使用相同的变量令人困惑;我个人会这样写,这是功能相同,但更容易理解:

cmd= lambda button=b: print(button) 
+0

谢谢,解决了这个问题! – user2304540 2013-04-29 19:33:27