I've put together a simple class that inherits from ttk.Entry
in order to toggle some placeholder text on focus events (based on this answer).
The odd thing is that my placeholder text is only cleared on '<FocusIn>'
if I include print(self['foreground'])
in my set_placeholder()
method, otherwise the placeholder text isn't cleared when the Entry is focused.
I've included an example app with two PlaceholderEntry
widgets to demonstrate the focus behavior.
import tkinter as tk
from tkinter import ttk
class Root(tk.Tk):
"""Example app"""
def __init__(self):
super().__init__()
self.ph_entry_a = PlaceholderEntry(self, 'Hello')
self.ph_entry_a.pack()
self.ph_entry_b = PlaceholderEntry(self, 'there')
self.ph_entry_b.pack()
class PlaceholderEntry(ttk.Entry):
"""Entry widget with focus-toggled placeholder text"""
def __init__(
self, parent, placeholder='', color='#828790', *args, **kwargs
):
super().__init__(parent, *args, **kwargs)
self.placeholder = placeholder
self._ph_color = color
self._default_fg = self.cget('foreground') # default foreground color
# focus bindings
self.bind('<FocusOut>', self.set_placeholder)
self.bind('<FocusIn>', self.clear_placeholder)
# initialize placeholder
self.set_placeholder()
def set_placeholder(self, *args): # on focus out
if not self.get(): # if the entry has no text...
self.insert(0, self.placeholder)
self.configure(foreground=self._ph_color)
# clearing the placeholder doesn't work without this line:
print(self['foreground'])
# I've also tried this, and it works as well...
# str(self.cget('foreground'))
def clear_placeholder(self, *args):
if self.cget('foreground') == self._ph_color:
self.delete(0, tk.END)
self.configure(foreground=self._default_fg)
# it makes no difference if I have a 'print' or 'str' statement here
if __name__ == '__main__':
app = Root()
app.mainloop()
I'm wondering if this has something to do with garbage collection, but I'm honestly not sure. For what it's worth, assigning the foreground
to a variable in the set_placeholder
method e.g. fg = self['foreground']
makes no difference. Can anybody tell me what's going on here? Any info is much appreciated.
FWIW: I'm using Python 3.11 64-bit on Windows 10