Python Tkinter错误:“标签没有__call__method”

时间:2015-03-13 11:16:58

标签: python tkinter

我试图创建一个Python tkinter登录注册但遇到一个小问题。

错误消息是:

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

1 个答案:

答案 0 :(得分:2)

问题在于这一行

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

定义名为Label的{​​{1}},从而遮蔽Label构造函数。然后,在LabelRegister类中创建几个标签(由这两个按钮触发),名称Login不再绑定到构造函数,而是绑定到特定标签

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

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() StringVara应该是bself.a
  • 您正尝试使用self.braw_input窗口小部件中获取用户输入;这是错的!相反,只需读取变量的值即可获得值,例如:而不是Entry,请使用self.User
  • 不要混用self.a.get()grid布局
  • pack检查该名称是否在该文件中
  • if self.User in 'username.txt'loginCheck应该是各自类的方法

一旦我在这里,这是我的代码版本(部分),以帮助您入门:

registerCheck

请注意,我将登录“数据库”从文件更改为字典,以简化操作并专注于Tkinter问题。当然,简单字典和纯文本文件都不是存储登录信息的适当方式。

另外,我将GUI小部件的创建和布局放在一行上。在这种情况下,这是可能的,因为我们不需要对这些小部件的引用,但要注意永远不要这样做。 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() ,因为这会将self.label = Label(...).grid(...)绑定到self.label的结果,而不会绑定到实际的grid

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