提示条目小部件 tkinter

hint entry widget tkinter

我正在尝试编写一个将显示登录屏幕的程序。我真的很想在条目小部件中显示某种提示。例如,在密码字段中,它将显示“输入密码”,一旦您单击该小部件,它就会变得清晰。 我已经实现了清除小部件的功能,但我无法将它连接到我的入口小部件。 有人可以帮忙吗?

"""

def login():
    db = sqlite3.connect('login.sqlite3')
    db.execute('CREATE TABLE IF NOT EXISTS login (email TEXT, passwort TEXT)')
    db.execute("INSERT INTO login(email, passwort) VALUES('admin','admin')")
    db.execute("INSERT INTO login(email, passwort) VALUES('powerpython.girls@alfspythonkurs.de','DafürGibtEsEine1+')")
    cur = db.cursor()
    cur.execute("SELECT * FROM login WHERE email=? AND passwort=?", (email_var.get(), password_var.get()))
    row = cur.fetchone()
    if row:
        messagebox.showinfo('Information', 'Login succesful')
    else:
        messagebox.showerror('Error','Login error')    

    cur.connection.commit()
    db.close()

login_screen    = tk.Tk()
login_screen.title("Login")

login_screen.geometry("1280x720+50+50")
login_screen.resizable(False, False)

email_var       = tk.StringVar()
password_var    = tk.StringVar()
 
def registration():
    
    # make docstring pretty
    """registration function:
        this function saves the password and email the user enters 
        then it prints them on the screen
    """
    email       = email_var.get()
    password    = password_var.get()
     
    print("Email : " + email)
    print("Password : " + password)
     
    email_var.set("")
    password_var.set("")

frame = LabelFrame(login_screen, text = "Login: ", pady = 10, padx = 10)
frame.grid(row = 0, column = 0, padx = 30, pady = 30)

name_label         = tk.Label(frame, text = 'Email', font=('arial',10, 'bold'))
name_label.grid(row=1,column=1, sticky = tk.W, padx = 5, pady = 5)


password_label     = tk.Label(frame, text = 'Password', font = ('arial',10,'bold'))
password_label.grid(row=2,column=1, sticky = tk.W, padx = 5, pady = 5)

entry_name         = tk.Entry(frame,textvariable = email_var, font=('arial',10,'normal'))
entry_name.grid(row=1,column=2, sticky = tk.W, padx = 5, pady = 5)

entry_password     = tk.Entry(frame, textvariable = password_var, font = ('arial',10,'normal'), show = '*')
entry_password.grid(row=2,column=2, sticky = tk.W, padx = 5, pady = 5)

submit_button      = tk.Button(frame,text = 'Submit', font = ('arial', 10, 'normal'), command = login) #davor ,command = registration
submit_button.grid(row=3,column=2)

class EntryWithPlaceholder(tk.Entry):
    def __init__(self, master=None, placeholder="PLACEHOLDER", color='grey'):
        super().__init__(master)

        self.placeholder = placeholder
        self.placeholder_color = color
        self.default_fg_color = self['fg']

        self.bind("<FocusIn>", self.foc_in)
        self.bind("<FocusOut>", self.foc_out)

        self.put_placeholder()

    def put_placeholder(self):
        self.insert(0, self.placeholder)
        self['fg'] = self.placeholder_color

    def foc_in(self, *args):
        if self['fg'] == self.placeholder_color:
            self.delete('0', 'end')
            self['fg'] = self.default_fg_color

    def foc_out(self, *args):
        if not self.get():
            self.put_placeholder()

login_screen.mainloop()

"""

简单的回答:您从未创建 EntryWithPlaceholder 的实例 class。

entry_password     = tk.Entry(frame, textvariable = password_var, font = ('arial',10,'normal'), show = '*')

这应该是:

entry_password     = EntryWithPlaceholder(frame, textvariable = password_var, font = ('arial',10,'normal'), show = '*')

我对 class 进行了一些更改以查看它是否确实有效。

class EntryWithPlaceholder(tk.Entry):
def __init__(self, master=None, font = None, placeholder="PLACEHOLDER", color='grey', textvariable = None):
    super().__init__()

    self.placeholder = placeholder
    self.placeholder_color = color
    self.default_fg_color = self['fg']
    self['textvariable'] = textvariable
    self.bind("<FocusIn>", self.foc_in)
    self.bind("<FocusOut>", self.foc_out)

    self.put_placeholder()

def put_placeholder(self):
    self.insert(0, self.placeholder)
    self['fg'] = self.placeholder_color

def foc_in(self, *args):
    if self['fg'] == self.placeholder_color:
        self['show'] = '*'
        self.delete('0', 'end')
        self['fg'] = self.default_fg_color

def foc_out(self, *args):
    if not self.get():
        self.put_placeholder()
        self['show'] = ''