0

我正在尝试使用 Tkinter 创建一个 gui,它获取用户名和密码并连接到远程服务器并执行一项功能。我将一些杂乱的代码拼凑在一起,它或多或少地起作用了,但是当我尝试在一个整洁的模块中重新创建它时,它就坏了。它可能是一个新手python错误,但我无法发现它。编辑:澄清一下,当它起作用时,唯一的类是 setupGui 并且任何方法都在该类下。现在我已经将 gui 与方法分开了,它不起作用。

class setupGui(object):
   def __init__(self, parent):
      ##omited general frame stuff 

       self.userIn = ttk.Entry(self.topFrame, width = 20)
       self.userIn.grid(row = 1, column = 1)
       self.passIn = ttk.Entry(self.topFrame, width = 20, show ="*")
       self.passIn.grid(row = 2, column = 1)

       #Buttons
       self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup())
       self.setupbtn.grid(row = 3, column = 0, pady = 10)

class setup(object):
   def__init__(self):
      self.userName = setupGui.userIn.get()
      self.userPass = setupGui.passIn.get()
   def startSetup(self):
      self.another_related_fucntion # about 4 related functions actually

if __name__ == '__main__':
root = Tk()
gui = setupGui(root)
root.mainloop()

而且,如果我没有将命令附加到按钮上,那么一切正常(但显然除了看起来很漂亮之外确实蹲着)。当我附加命令时,我收到了这个错误:

Traceback (most recent call last):
 File "macSetup.py", line 211, in <module>
 gui = setupGui(root)
 File "macSetup.py", line 45, in __init__
self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup())
File "macSetup.py", line 69, in __init__
self.userName = setupGui.userIn.get()
AttributeError: type object 'setupGui' has no attribute 'userIn'
4

3 回答 3

1

在您的代码中,userIn设置为setupGui对象的实例变量,而不是setupGui类本身的属性。

最简单的解决方案是将setupGuisetup类合并startSetup为 的方法setupGui,然后command=self.startSetup在初始化时使用setupbtn-this 调用startSetup作为绑定方法,self因此应该引用该setupGui对象,然后您可以使用该对象,self.userIn.get()然后继续使用self.passIn.get()

如果您希望将类中的逻辑保留在setup类之外,则setupGui可以像这样将其分开:

class setup(object):
    def __init__(self, username, userpass):
        self.userName = username
        self.userPass = userpass

    def startSetup(self):
        # as before

然后将此方法添加到setupGui类中:

def dosetup(self):
    setup(self.userIn.get(), self.passIn.get()).startSetup()

并实例化Buttonwith command=self.dosetup。(我个人会让这个setup类成为一个独立的函数,但我不知道你的startSetup例程实际上有多复杂,所以我认为你有充分的理由让它成为一个类。)

于 2012-05-18T19:14:09.563 回答
1

command属性引用了一个函数,但您正在调用该函数并将结果提供给该command属性。最终结果是您在创建按钮时调用 setup 函数,而不是在单击按钮时调用。事情还没有完全初始化,所以你得到了错误。

你这样做:

self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup()) 

...当你应该做这样的事情时:

self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup) 

请注意缺少尾随()on startSetup

如果您不想setup在单击按钮之前实例化,您有几个选择。可以说,最好的方法是创建一个方法:

def _launch_setup(self):
    setup().setupGui()
...
self.setupbtn = ttk.Button(..., command=self._launch_setup)

您也可以使用 lambda,但在这种情况下,我推荐使用命名方法。

于 2012-05-18T20:38:28.627 回答
0

setupGui本身没有属性userIn

在您的__init__方法中,setupGui将属性赋予实例,而不是类。

于 2012-05-18T19:11:19.200 回答