-1

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()
Moti Shakuri
  • 33
  • 10
  • 1
    Using this [answer](https://stackoverflow.com/a/47928390/7032856) you should rather just use colors to tell if the password is set or not, instead of checking if it's exactly empty or not. – Nae Dec 22 '17 at 14:21
  • 1
    So, the question you're asking is how do placeholder text while also allowing the user to enter the exact same thing as the placeholder text? – Bryan Oakley Dec 22 '17 at 14:23
  • @BryanOakley yes, that pretty much says it all, im gonna edit it, my english isnt that great so i couldnt find the right explanation – Moti Shakuri Dec 22 '17 at 14:24
  • Isn't both `enter username` and `insert password` are invalid anyway according to the no space rule? So why bother? – Nae Dec 22 '17 at 14:25
  • @Nae well thats true right now, but i want to do it anyway, both to learn new things and also to make it cleaner to the user – Moti Shakuri Dec 22 '17 at 14:26

1 Answers1

1

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()
Nae
  • 14,209
  • 7
  • 52
  • 79
  • thank you man, i dont really get it, but thats on me alredy lol, gonna sit on it a bit. – Moti Shakuri Dec 22 '17 at 14:49
  • @It just changes the color of the entry widget's text when putting placeholder, and if it's the placeholder color it assumes it is empty. You can probably do a similar check using a flag like you have as `emptyuser`. – Nae Dec 22 '17 at 14:54