Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多个类和Tkinter的Python属性错误_Python_User Interface_Attributes_Tkinter_Syntax Error - Fatal编程技术网

具有多个类和Tkinter的Python属性错误

具有多个类和Tkinter的Python属性错误,python,user-interface,attributes,tkinter,syntax-error,Python,User Interface,Attributes,Tkinter,Syntax Error,我正在尝试使用Tkinter创建一个gui,它获取用户名和密码,连接到远程服务器并执行一个功能。我拼凑了一些乱七八糟的代码,它或多或少起了作用,但当我试图在一个整洁的模块中重新创建它时,它坏了。这可能是一个新手python错误,但我无法发现它。编辑:为了澄清,当它工作时,唯一的类是setupGui,任何方法都在该类下。既然我已经将gui与方法分离,它就不起作用了 class setupGui(object): def __init__(self, parent): ##omit

我正在尝试使用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'
回溯(最近一次呼叫最后一次):
文件“macSetup.py”,第211行,在
gui=设置gui(根目录)
文件“macSetup.py”,第45行,在_init中__
self.setupbtn=ttk.Button(self.topFrame,text=“启动设置”,command=Setup().startSetup())
文件“macSetup.py”,第69行,在_init中__
self.userName=setupGui.userIn.get()
AttributeError:类型对象“setupGui”没有属性“userIn”

setupGui
本身没有属性
userIn


setupGui
\uuuuu init\uuuuu
方法中,将属性赋予实例,而不是类。

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

最简单的解决方案是合并
setupGui
setup
类,将
startSetup
作为
setupGui
的一种方法移入,然后在初始化
setupbtn
时使用
command=self.startSetup
——这将
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
self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup) 
然后将此方法添加到
setupGui
类:

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

并使用
command=self.dosetup
实例化
按钮。(我个人会将
设置
类设置为一个独立的函数,但我不知道
启动设置
例程实际上有多复杂,因此我认为您有充分的理由将其设置为类。)

命令
属性引用函数,但是您正在调用函数并将结果提供给
命令
属性。最终的结果是,您在创建按钮时调用设置函数,而不是在单击按钮时。事情还没有完全初始化,所以您会得到错误

您正在这样做:

self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup()) 
。。。当你应该这样做的时候:

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

    def startSetup(self):
        # as before
self.setupbtn = ttk.Button(self.topFrame, text = "Start Setup", command = setup().startSetup) 
注意
startSetup
上缺少尾随的
()

如果在单击按钮之前不想实例化
设置
,则有两种选择。可以说,最好的方法是创建一种方法:

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

您也可以使用lambda,但在本例中,我建议使用命名方法。

我最初就是这样设置的。我通常不喜欢将函数与GUI混合在一起。在Java中,我甚至可以将它们放在单独的包中。我尝试将self.userName=setupGui.userIn.get()更改为self.userName=setupGui(root.userIn.get(),但出现了一个疯狂的递归错误。我也尝试用gui代替root(因为它在main中定义),但它说它未定义。哪一条路线更像蟒蛇路线?请参见编辑。我想这对你有用。(实际上,请看最近的编辑,因为我第一次把
dosetup
搞砸了。)