2015-03-13 66 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

相關問題