2015-03-13 50 views
-2

我试图创建一个Python tkinter登录注册,但遇到一个小问题。Python Tkinter错误:“Label has no __call__method”

的错误信息是:

self.Label_Name = Label(top, text="What is your username: ") 
AttributeError: Label instance has no __call__ method 

可以请你校对我的代码:

from Tkinter import * 

class Register: 
    def __init__(self, parent): 
     top = self.top = Toplevel(parent) 

     # Variables to store the entries 
     self.VarEntUser = StringVar() 
     self.VarEntPass = StringVar() 
     self.VarEntRetype = StringVar() 

     self.Label_Name = Label(top, text="What is your username: ") 
     self.Label_Password = Label(top, text="Enter a password: ") 
     self.Label_Retype = Label(top, text="Retype Password: ") 

     # Entry fields for the user to enter there details 
     self.Ent_Name = Entry(top, textvariable=self.VarEntUser) 
     self.Ent_Password = Entry(top, textvariable=self.VarEntPass) 
     self.Ent_Retype = Entry(top, textvariable=self.VarEntRetype) 

     # Puts all the fields ^, into the window 
     self.Label_Name.grid(row=0, sticky=W) 
     self.Label_Password.grid(row=1, sticky=W) 
     self.Label_Retype.grid(row=2, sticky=W) 

     self.Ent_Password.grid(row=1, column=1) 
     self.Ent_Retype.grid(row=2, column=1) 
     self.Ent_Name.grid(row=0, column=2) 

     # Run the RegisterCheck function 
     # submit button which Checks the Entered details then writes the user and pass to a .txt file 
     self.MySubmitButton = Button(top, text='Submit', command=RegisterCheck) 
     self.MySubmitButton.pack() 

     self.U = raw_input(self.VarEntUser.get()) 
     self.P = raw_input(self.VarEntPass.get()) 
     self.R = raw_input(self.VarEntRetype.get()) 


class LogIn: 
    def __init__(self, parent): 
     top = self.top = Toplevel(parent) 
     self.a = StringVar() 
     self.b = StringVar() 

     self.Label_Log_User1 = Label(top, text='Username:') 
     self.Label_Log_Pass = Label(top, text='Password: ') 

     self.Ent_User_Log = Entry(top, textvariable=self.a) 
     self.Ent_Pass_Log = Entry(top, textvariable=self.b) 

     self.Label_Log_User1.grid(row=1) 
     self.Pass_Log.grid(row=2) 
     self.EntUserLog.grid(row=1, column=1) 
     self.EntPassLog.grid(row=2, column=1) 

     self.User = raw_input(self.EntUserLog.get()) 
     self.Pass = raw_input(self.EntUserLog.get()) 
     # runs the 'LoginCheck' function 
     self.LogInButton = Button(top, text="Log In", command=LogInCheck) 
     self.LogInButton.pack() 


def LogInCheck(self): 
    # Checks if the fields are blanking displaying an error 
    if len(self.User) <= 0 and len(self.Pass) <= 0: 
     print "Please fill in all fields." 
    else: 
     pass 

    # Checks to see if the user and pass have been created 
    if self.User in 'username.txt' and self.Pass in 'password': 
     print 'You are now logged in!' 
    else: 
     print "Log in Failed" 


def RegisterCheck(self): 
    # Checks if the fields are blank 
    if len(self.P) <= 0 and len(self.U) <= 0: 
     print "Please fill out all fields." 
    else: 
     pass 
    # Check is the password and the retype match 
    if self.P == self.R: 
     pass  
    else: 
     print "Passwords do not match" 

    # After registering write the user and pass to a .txt file  
    with open('username.txt', 'a') as fout: 
     fout.write(self.U + '\n') 

    with open('password.txt', 'a') as fout: 
     fout.write(self.P + '\n') 

# Depending on what the user chooses, either log in or register than opens the specific window 

def launch_Register(): 
    inputDialog = Register(root) 
    root.wait_window(inputDialog.top) 

def launch_LogIn(): 
    inputdialog2 = LogIn(root) 
    root.wait_window(inputdialog2.top) 

root = Tk() 

label = Label(root, text='Choose an option') 
label.pack() 

loginB = Button(root, text='Log In', command=launch_LogIn) 
loginB.pack() 

registerB = Button(root, text='Register', command=launch_Register) 
registerB.pack() 

root.mainloop() 

回答

2

的问题是,在这条线

Label = Label(root, text='Choose an option') 

你定义一个LabelLabel,因此遮蔽了Label构造河然后,然后在RegisterLogin类中创建几个标签(由这两个按钮触发),名称Label不再绑定到构造函数,而是绑定到该特定标签。

更改标签的名称,然后它应该工作。另外,我建议你使用小写名称来表示变量和方法。仅这一点可能有助于防止许多此类错误。

root = Tk() 

label = Label(root, text='Choose an option') 
label.pack() 

loginB = Button(root, text='Log In', command=launch_LogIn) 
loginB.pack() 

registerB = Button(root, text='Register', command=launch_Register) 
registerB.pack() 

root.mainloop() 

注意,有 几个 许多更多的问题与您的代码:

  • StringVarab大概应该是self.aself.b
  • 您正在尝试使用raw_input获得用户输入i ñEntry部件;这是错误的!相反,只需读取变量的值即可获得值,例如而不是self.User,使用
  • 不混合gridpack布局
  • if self.User in 'username.txt'这个名字不检查是否是在该文件
  • loginCheckregisterCheck应相应类的方法

一旦我找到了,这是我的代码版本(的一部分),以帮助您取得明星特德:

class Register: 

    def __init__(self, parent): 
     top = self.top = Toplevel(parent) 
     self.var_user = StringVar() 
     self.var_pass = StringVar() 
     self.var_retype = StringVar() 

     Label(top, text="What is your username: ").grid(row=0, sticky=W) 
     Label(top, text="Enter a password: ").grid(row=1, sticky=W) 
     Label(top, text="Retype Password: ").grid(row=2, sticky=W) 
     Entry(top, textvariable=self.var_user).grid(row=0, column=1) 
     Entry(top, textvariable=self.var_pass).grid(row=1, column=1) 
     Entry(top, textvariable=self.var_retype).grid(row=2, column=1) 
     Button(top, text='Submit', command=self.registerCheck).grid(row=3) 

    def registerCheck(self): 
     u, p, r = self.var_user.get(), self.var_pass.get(), self.var_retype.get() 
     if p and u: 
      if p == r: 
       logins[u] = p 
      else: 
       print "Passwords do not match" 
     else: 
      print "Please fill out all fields." 

class LogIn: 

    # analogeous to Register; try to figure this out xourself 

def launch_Register(): 
    inputDialog = Register(root) 
    root.wait_window(inputDialog.top) 

def launch_LogIn(): 
    inputDialog = LogIn(root) 
    root.wait_window(inputDialog.top) 

logins = {} 
root = Tk() 
Label(root, text='Choose an option').pack() 
Button(root, text='Log In', command=launch_LogIn).pack() 
Button(root, text='Register', command=launch_Register).pack() 
root.mainloop() 

注意,我改变了从文件中登录“数据库”的字典让事情变得简单和专注于Tkinter的问题。当然,简单字典和纯文本文件都不适合存储登录信息。

此外,我将GUI小部件的创建和布局放在一行上。在这种情况下,这是可能的,因为我们不需要引用这些小部件,但是请注意不要做例如self.label = Label(...).grid(...),因为这会将self.label绑定到grid的结果,而不是实际的Label

最后,这仍将打印所有消息到标准输出。相反,你应该为此添加另一个Label,或者打开一个消息对话框,但这是作为练习留给读者...

+0

嘿谢谢我修好了一切,但当我点击注册或登录它只是冻结它dosnt打开一个新窗口? – Ramazan 2015-03-14 00:35:26

+0

@tobias_k:因为您调用'raw_input'而冻结。它正在等待您在命令窗口中输入某些内容。 – 2015-03-14 14:27:19

+0

@BryanOakley是的,我已经找到了那一点。查看我的更新(s)。原来代码中存在其他问题_Lots_,并且'Label'只是冰山一角...... – 2015-03-14 14:30:03

相关问题