added placeholder text to CTkEntry

This commit is contained in:
Tom Schimansky 2022-02-04 21:28:37 +01:00
parent f5cac7b978
commit 5f9c30aeaf
6 changed files with 48 additions and 12 deletions

View File

@ -1,4 +1,4 @@
__version__ = "2.0" __version__ = "2.1"
from .customtkinter_button import CTkButton from .customtkinter_button import CTkButton
from .customtkinter_slider import CTkSlider from .customtkinter_slider import CTkSlider

View File

@ -8,6 +8,7 @@ class CTkColorManager:
MAIN_HOVER = None MAIN_HOVER = None
ENTRY = None ENTRY = None
TEXT = None TEXT = None
PLACEHOLDER_TEXT = None
LABEL_BG = None LABEL_BG = None
SLIDER_BG = None SLIDER_BG = None
SLIDER_PROGRESS = None SLIDER_PROGRESS = None
@ -26,6 +27,7 @@ class CTkColorManager:
cls.MAIN_HOVER = ("#5FB4DD", "#5FB4DD") cls.MAIN_HOVER = ("#5FB4DD", "#5FB4DD")
cls.ENTRY = ("white", "#222222") cls.ENTRY = ("white", "#222222")
cls.TEXT = ("black", "white") cls.TEXT = ("black", "white")
cls.PLACEHOLDER_TEXT = ("gray52", "gray62")
cls.LABEL_BG = ("white", "#626061") cls.LABEL_BG = ("white", "#626061")
cls.SLIDER_BG = ("#6B6B6B", "#222222") cls.SLIDER_BG = ("#6B6B6B", "#222222")
cls.SLIDER_PROGRESS = ("#A5A6A5", "#555555") cls.SLIDER_PROGRESS = ("#A5A6A5", "#555555")

View File

@ -13,7 +13,9 @@ class CTkEntry(tkinter.Frame):
bg_color=None, bg_color=None,
fg_color="CTkColorManager", fg_color="CTkColorManager",
text_color="CTkColorManager", text_color="CTkColorManager",
placeholder_text_color="CTkColorManager",
text_font=None, text_font=None,
placeholder_text=None,
corner_radius=8, corner_radius=8,
width=120, width=120,
height=30, height=30,
@ -52,6 +54,7 @@ class CTkEntry(tkinter.Frame):
self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color self.bg_color = self.detect_color_of_master() if bg_color is None else bg_color
self.fg_color = CTkColorManager.ENTRY if fg_color == "CTkColorManager" else fg_color self.fg_color = CTkColorManager.ENTRY if fg_color == "CTkColorManager" else fg_color
self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color self.text_color = CTkColorManager.TEXT if text_color == "CTkColorManager" else text_color
self.placeholder_text_color = CTkColorManager.PLACEHOLDER_TEXT if placeholder_text_color == "CTkColorManager" else placeholder_text_color
if text_font is None: if text_font is None:
if sys.platform == "darwin": # macOS if sys.platform == "darwin": # macOS
@ -63,9 +66,12 @@ class CTkEntry(tkinter.Frame):
else: else:
self.text_font = text_font self.text_font = text_font
self.placeholder_text = placeholder_text
self.placeholder_text_active = False
self.pre_placeholder_arguments = {} # some set arguments of the entry will be changed for placeholder and then set back
self.width = width self.width = width
self.height = height self.height = height
self.corner_radius = self.calc_optimal_corner_radius(corner_radius) # optimise for less artifacts self.corner_radius = self.calc_optimal_corner_radius(corner_radius) # optimise for less artifacts
if self.corner_radius*2 > self.height: if self.corner_radius*2 > self.height:
@ -91,8 +97,12 @@ class CTkEntry(tkinter.Frame):
self.fg_parts = [] self.fg_parts = []
self.bind('<Configure>', self.update_dimensions) super().bind('<Configure>', self.update_dimensions)
self.entry.bind('<FocusOut>', self.set_placeholder)
self.entry.bind('<FocusIn>', self.clear_placeholder)
self.draw() self.draw()
self.set_placeholder()
def destroy(self): def destroy(self):
AppearanceModeTracker.remove(self.change_appearance_mode) AppearanceModeTracker.remove(self.change_appearance_mode)
@ -132,6 +142,23 @@ class CTkEntry(tkinter.Frame):
self.draw() self.draw()
def set_placeholder(self, event=None):
if self.placeholder_text is not None:
if not self.placeholder_text_active and self.entry.get() == "":
self.placeholder_text_active = True
self.pre_placeholder_arguments = {"show": self.entry.cget("show")}
self.entry.config(fg=CTkColorManager.single_color(self.placeholder_text_color, self.appearance_mode), show="")
self.entry.delete(0, tkinter.END)
self.entry.insert(0, self.placeholder_text)
def clear_placeholder(self, event=None):
if self.placeholder_text_active:
self.placeholder_text_active = False
self.entry.config(fg=CTkColorManager.single_color(self.text_color, self.appearance_mode))
self.entry.delete(0, tkinter.END)
for argument, value in self.pre_placeholder_arguments.items():
self.entry[argument] = value
def draw(self): def draw(self):
self.canvas.delete("all") self.canvas.delete("all")
self.fg_parts = [] self.fg_parts = []
@ -189,6 +216,9 @@ class CTkEntry(tkinter.Frame):
self.entry.configure(fg=self.text_color, self.entry.configure(fg=self.text_color,
insertbackground=self.text_color) insertbackground=self.text_color)
def bind(self, *args, **kwargs):
self.entry.bind(*args, **kwargs)
def config(self, *args, **kwargs): def config(self, *args, **kwargs):
self.configure(*args, **kwargs) self.configure(*args, **kwargs)
@ -228,13 +258,19 @@ class CTkEntry(tkinter.Frame):
self.draw() self.draw()
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
return self.entry.delete(*args, **kwargs) self.entry.delete(*args, **kwargs)
self.set_placeholder()
return
def insert(self, *args, **kwargs): def insert(self, *args, **kwargs):
self.clear_placeholder()
return self.entry.insert(*args, **kwargs) return self.entry.insert(*args, **kwargs)
def get(self): def get(self):
return self.entry.get() if self.placeholder_text_active:
return ""
else:
return self.entry.get()
def change_appearance_mode(self, mode_string): def change_appearance_mode(self, mode_string):
if mode_string.lower() == "dark": if mode_string.lower() == "dark":

View File

@ -46,13 +46,11 @@ class App(customtkinter.CTk):
fg_color=("gray70", "gray20"), text="CustomTkinter\ninterface example") fg_color=("gray70", "gray20"), text="CustomTkinter\ninterface example")
self.label_1.place(relx=0.5, rely=0.3, anchor=tkinter.CENTER) self.label_1.place(relx=0.5, rely=0.3, anchor=tkinter.CENTER)
self.entry_1 = customtkinter.CTkEntry(master=self.frame, corner_radius=20, width=200) self.entry_1 = customtkinter.CTkEntry(master=self.frame, corner_radius=20, width=200, placeholder_text="username")
self.entry_1.place(relx=0.5, rely=0.52, anchor=tkinter.CENTER) self.entry_1.place(relx=0.5, rely=0.52, anchor=tkinter.CENTER)
self.entry_1.insert(0, "username")
self.entry_2 = customtkinter.CTkEntry(master=self.frame, corner_radius=20, width=200, show="*") self.entry_2 = customtkinter.CTkEntry(master=self.frame, corner_radius=20, width=200, show="*", placeholder_text="password")
self.entry_2.place(relx=0.5, rely=0.6, anchor=tkinter.CENTER) self.entry_2.place(relx=0.5, rely=0.6, anchor=tkinter.CENTER)
self.entry_2.insert(0, "password")
self.button_2 = customtkinter.CTkButton(master=self.frame, text="Login", self.button_2 = customtkinter.CTkButton(master=self.frame, text="Login",
corner_radius=6, command=self.button_event, width=200) corner_radius=6, command=self.button_event, width=200)

View File

@ -10,7 +10,7 @@ root_tk.title("CustomTkinter Test")
def button_function(): def button_function():
print("Button click") print("Button click", label_1.text_label.cget("text"))
def slider_function(value): def slider_function(value):
@ -40,7 +40,7 @@ slider_1 = customtkinter.CTkSlider(master=frame_1, command=slider_function, from
slider_1.pack(pady=y_padding, padx=10) slider_1.pack(pady=y_padding, padx=10)
slider_1.set(0.5) slider_1.set(0.5)
entry_1 = customtkinter.CTkEntry(master=frame_1) entry_1 = customtkinter.CTkEntry(master=frame_1, placeholder_text="CTkEntry")
entry_1.pack(pady=y_padding, padx=10) entry_1.pack(pady=y_padding, padx=10)
checkbox_1 = customtkinter.CTkCheckBox(master=frame_1, command=check_box_function) checkbox_1 = customtkinter.CTkCheckBox(master=frame_1, command=check_box_function)

View File

@ -19,7 +19,7 @@ def read(filename):
setup(name="customtkinter", setup(name="customtkinter",
version="2.0", version="2.1",
author="Tom Schimansky", author="Tom Schimansky",
license="Creative Commons Zero v1.0 Universal", license="Creative Commons Zero v1.0 Universal",
url="https://github.com/TomSchimansky/CustomTkinter", url="https://github.com/TomSchimansky/CustomTkinter",