Search code examples
pythontkinterwidgetbordertkinter-entry

How to change a entry widgets border color in Python Tkinter


I am working on a program that has a entry widget. And when the user clicks a button and that entry widget is empty then the program will change the border color of it to red. But when I try the border just stays the same color, which is black.

Here is the code:

self.timeField = Entry(self.mfr, width=40, relief=SOLID, highlightbackground="red", highlightcolor="red")
self.timeField.grid(row=0, column=1, sticky=W)

Then in the if statement that checks if it is empty has this to change it to red but it does not seem to work:

self.timeField.config(highlightbackground="red")
self.timeField.config(highlightcolor="red")

Can someone explain to me why this is not working, what I am doing wrong, and a way to fix it? Thanks in advance.

Update: Here is the rest of the code as requested:

def start(self):
    waitTime = self.timeField.get()
    password = self.passField.get()

    cTime = str(self.tVers.get())
    self.cTime = cTime

    if waitTime.strip() != "":
        if password.strip() != "":
            if waitTime.isdigit():
                if self.cTime == "Secs":
                    waitTime = int(waitTime)
                elif self.timeVer == "Mins":
                    waitTime = int(waitTime) * 60
                else:
                    waitTime = int(waitTime) * 3600

                self.password = password

                root.withdraw()
                time.sleep(float(waitTime))
                root.deiconify()
                root.overrideredirect(True)
                root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))

                self.tfr.destroy()
                self.mfr.destroy()
                self.bfr.destroy()

                self.create_lockScreen()
            else:
                self.timeField.configure(highlightcolor="red")
        else:
            self.passFields.configure(highlightcolor="red")
    else:
        self.timeField.config(highlightbackground="red", highlightcolor="red")

Solution

  • Addressing the issue with highlightthickness

    The code you've given should work, though you may be bumping up against platform implementation (ie: windows may not treat the highlightthickness the same as other platforms)

    Here's a program that should work, though I haven't tested it on windows 7:

    import Tkinter as tk
    
    class Example(tk.Frame):
        def __init__(self, parent):
            tk.Frame.__init__(self, parent)
    
            self.entry = tk.Entry(self)
            self.button = tk.Button(self, text="Validate", command=self.validate)
            self.entry.pack(side="top", fill="x")
            self.button.pack(side="bottom")
    
            self.validate() # initialize the border
    
        def validate(self):
            data = self.entry.get()
            if len(data) == 0:
                self.entry.configure(highlightbackground="red", highlightcolor="red")
            else:
                self.entry.configure(highlightbackground="blue", highlightcolor="blue")
    
    
    if __name__ == "__main__":
        root = tk.Tk()
        Example(root).pack(fill="both", expand=True)
        root.mainloop()
    

    Using a frame to simulate a border

    Another solution is to create a border with a frame that is just slightly larger than the button. Here's a quick example. Its not really production ready, but it illustrates the point:

    import Tkinter as tk
    
    class Example(tk.Frame):
        def __init__(self, parent):
            tk.Frame.__init__(self, parent)
    
            self.entry = CustomEntry(self)
            self.button = tk.Button(self, text="Validate", command=self.validate)
            self.entry.pack(side="top", fill="x")
            self.button.pack(side="bottom")
    
            self.validate() # initialize the border
    
        def validate(self):
            data = self.entry.get()
            if len(data) == 0:
                self.entry.set_border_color("red")
            else:
                self.entry.set_border_color("blue")
    
    class CustomEntry(tk.Frame):
        def __init__(self, parent, *args, **kwargs):
            tk.Frame.__init__(self, parent)
            self.entry = tk.Entry(self, *args, **kwargs)
            self.entry.pack(fill="both", expand=2, padx=2, pady=2)
    
            self.get = self.entry.get
            self.insert = self.entry.insert
    
        def set_border_color(self, color):
            self.configure(background=color)
    
    if __name__ == "__main__":
        root = tk.Tk()
        Example(root).pack(fill="both", expand=True)
        root.mainloop()