Search code examples
pythontkintertkinter-entry

how to put default text on tkinter's entry widget


so, i opened a question about it yesterday but it got closed saying its a dupe, let me explain my question more specificly then, hoping im not passinng any law here..

im trying to set a default message that will be set as gray and low opacity in the entry widget on tkinter, that after being focused in will dispear.

i managed to do that, but i got into a problem.

the default text is "enter username" for example, but if someone tries to do this user name it says that the username entry is empty which isnt what i wanna do..

i hope you understood my question.

edit: my question is how to do a placeholder text, while allowing the user to input the same text as the placeholder.

thanks in advance, this is my code:

    from tkinter import *
from tkinter import messagebox


main = Tk()
main.title("ani gever")
checkbox_var = IntVar()


def delete_user_default(event):
    if User_entry.get()!="enter username":
        pass
    else:
        User_entry.delete(0, END)

def delete_password_default(event):
    if password_entry.get() !="insert password":
        pass
    else:
        password_entry.delete(0, END)
        password_entry.config(show="*")

def return_user_default(event):
    if User_entry.get()=="":
        User_entry.insert(0, "enter username")
        emptyuser=1
    else:
        pass

def return_password_default(event):
    if password_entry.get()=="":
        password_entry.insert(0,"insert password")
        password_entry.config(show="")
    else:
        pass

def details(event):
    if ((User_entry.get() == "enter username") or (password_entry.get() == "insert password")):
        errorLabel.config(text="Username or password is empty!",fg="red")
    elif ((" " in User_entry.get()) or " " in password_entry.get()):
        errorLabel.config(text="dont use spaces in your password or username!", fg="red")
    else:
        print ("username:" + User_entry.get() + "\npassword:" + password_entry.get())
        errorLabel.config(text="")


#============== define texts=======================
User_label= Label(main,text="Username:")
password_label= Label(main,text="Password:")
User_entry = Entry(main)
password_entry= Entry(main,show="*")
enterButton= Button(main,text="Log in")
errorLabel= Label(main,text="")
#=============default text on entry's=============
password_entry.config(show="")
User_entry.insert(0,"enter username")
password_entry.insert(0,"insert password")
User_entry.bind("<FocusIn>",delete_user_default)
password_entry.bind("<FocusIn>",delete_password_default)
User_entry.bind("<FocusOut>",return_user_default)
password_entry.bind("<FocusOut>",return_password_default)

#=============return user details ===========
User_entry.bind("<Return>",details)
password_entry.bind("<Return>",details)
enterButton.bind("<Button-1>",details)



#=============place everything on screen===========
User_label.grid(row=0,sticky= W)
User_entry.grid(row=0,column=1,sticky= W)
password_label.grid(row=1,sticky= W)
password_entry.grid(row=1,column=1,sticky= W)
enterButton.grid(row=2,sticky=W)
errorLabel.grid(row=3,columnspan=10,sticky= W)

main.mainloop()

Solution

  • Using this answer an is_empty function can be created. It prints True if validated entry is 'empty' and False if not.

    import tkinter as tk
    
    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()
    
    def is_empty(widget, empty_color):
    
        if widget.get():
            if widget['fg'] == empty_color:
                print (True)
            else:
                print (False)
        else:
            print (True)
    
    
    if __name__ == "__main__":
        root = tk.Tk()
    
        username = EntryWithPlaceholder(root, "username")
        password = EntryWithPlaceholder(root, "password", 'blue')
        username.pack()
        password.pack()
    
        tk.Button(root, text="Validate",
                        command=lambda wid=username, clr=username.placeholder_color:
                                                        is_empty(wid, clr)).pack()
    
        root.mainloop()