如何让Tkinter Entry组件实现占位符与密码星号显示的正常切换
修复方案
问题根因
你的代码存在两处逻辑错误导致失焦显示异常:
- 失焦事件的
show属性处理错误:focus_out方法中无论输入框是否有内容,都统一将show设为None,如果输入框有内容会直接导致密码明文泄露;如果输入框为空,插入占位符时也没有关闭show属性,导致占位符文本被渲染为星号 - 占位符插入逻辑缺失:
insert_placeholder方法没有同步关闭show属性,占位符文本无法正常展示
修复后完整代码
from tkinter import * import os class PlaceholderEntry(Entry): def __init__(self, master=None, placeholder="", placefg='grey', bg='white', fg='black', insertbackground="black", show=None): super().__init__(master) self.placeholder = placeholder self.placefg = placefg self.normal_fg = fg self.show_char = show self['bg'] = bg self['insertbackground'] = insertbackground self.bind("<FocusIn>", self.focus_in) self.bind("<FocusOut>", self.focus_out) self.insert_placeholder() def insert_placeholder(self): self.delete(0,'end') self.insert(0, self.placeholder) self['fg'] = self.placefg # 插入占位符时关闭字符隐藏 self['show'] = '' def focus_in(self, *args): if self['fg'] == self.placefg: self.delete('0', 'end') self['fg'] = self.normal_fg # 获得焦点时恢复设置的隐藏字符 self['show'] = self.show_char def focus_out(self, *args): if not self.get(): self.insert_placeholder() else: # 有内容时保持字符隐藏 self['show'] = self.show_char os.system('cls' if os.name == 'nt' else 'clear') root = Tk() root.title("entry") root.geometry("400x400") root.configure(bg='#222222') c = ("#ffffff", "#222222", "#111111","#555555","#000000") username = Entry(root, show="*") password = PlaceholderEntry(root, show="*", placeholder="password", placefg=c[3], bg=c[2],fg=c[0], insertbackground=c[0]) username.pack() password.pack() root.mainloop()
关键修改点
- 重命名了属性避免和内置关键字冲突,移除了无意义的
self.none变量 - 插入占位符时强制关闭
show属性,确保占位符文本正常显示 - 失焦时判断输入框状态:为空则插入占位符,有内容则保持密码隐藏状态
内容的提问来源于stack exchange,提问作者R Cuccurullo
相关产品推荐
相关产品推荐

