以程序方式向 tkinter Entry 小部件添加占位符 [英] Adding placeholders to tkinter Entry widget in a procedural way
问题描述
我知道这个问题已经在这个网站上得到了回答,但我正在寻找一个更简单的答案,我以前看过一个,但后来这个问题被删除了或者其他什么,我找不到它.希望有人有更好、更简单的方法来解决它.与 class 相关的东西可能会更好,因为我可以轻松地将它与更多 Entry
小部件
I know this Q has been answered in this site, but im looking for a more simpler answer, and ive seen one before but then the question has been deleted or something, I cant find it. Hopefully someone is having a better and easier way around to it. Something related to class might be better as I could use it easily with more Entry
widgets
这是一个片段:
from tkinter import *
root = Tk()
def remove(event):
e.delete(0, END)
e = Entry(root)
e.insert(0, 'PLACEHOLDER')
e.pack(padx=100,pady=(30,0))
e.bind('<FocusIn>', remove)
e2 = Entry(root)
e2.pack( pady=(20,100))
root.mainloop()
是的,一旦它失去焦点并再次获得焦点,这将删除框内的所有其他项目,包括我们最初输入的文本.无论如何,要解决这个问题并使用 tkinter 拥有一个完美的占位符,我知道没有内置的方法.
Yes, this will remove all the other items inside of the box once it looses focus and gains it again, including the text we enter at first. Anyway to get around that and have a perfect placeholder with tkinter, I'm aware there is no inbuilt way.
提前致谢:D
推荐答案
这是一个非常简单的例子.在此示例中,我们包含了一些功能/注意事项:
Here is a very simple example. In this example we include a couple of features/caveats:
- 占位符的幻影文本
entry.input
将返回None
如果它的文本是占位符或为空entry.input
应该用来代替.get()
和.insert()
..input
逻辑旨在为您提供此类小部件的正确结果..get()
不够智能,无法返回正确的数据,并且.insert()
已重新配置为.input
- 在您键入时占位符被杂耍
- 占位符可以用
.insert()
覆盖 ~ 无需使用.delete()
.你仍然应该使用entry.input
代替
- ghost text for the placeholder
entry.input
will returnNone
if it's text is the placeholder or emptyentry.input
should be used in place of.get()
and.insert()
. The.input
logic is designed to give you the proper results for this type of widget..get()
is not smart enough to return the proper data, and.insert()
has been reconfigured as a proxy to.input
- placeholder is juggled while you type
- placeholder can be overwritten with
.insert()
~ no need to use.delete()
. You should still useentry.input
instead
#widgets.py
import tkinter as tk
class PlaceholderEntry(tk.Entry):
'''
All Of These Properties Are For Convenience
'''
@property
def input(self):
return self.get() if self.get() not in [self.__ph, ''] else None
@input.setter
def input(self, value):
self.delete(0, 'end')
self.insert(0, value)
self.configure(fg = self.ghost if value == self.__ph else self.normal)
@property
def isempty(self) -> bool:
return self.get() == ''
@property
def isholder(self) -> bool:
return self.get() == self.__ph
def __init__(self, master, placeholder, **kwargs):
tk.Entry.__init__(self, master, **{'disabledforeground':'#BBBBBB', **kwargs})
self.normal = self['foreground']
self.ghost = self['disabledforeground']
self.__ph = placeholder
self.input = placeholder
vcmd = self.register(self.validate)
self.configure(validate='all', validatecommand=(vcmd, '%S', '%s', '%d'))
self.bind('<FocusIn>' , self.focusin)
self.bind('<FocusOut>', self.focusout)
self.bind('<Key>' , self.check)
#rewire .insert() to be a proxy of .input
def validate(self, action_text, orig_text, action):
if action == '1':
if orig_text == self.__ph:
self.input = action_text
return True
#removes placeholder if necessary
def focusin(self, event=None):
if self.isholder:
self.input = ''
#adds placeholder if necessary
def focusout(self, event=None):
if self.isempty:
self.input = self.__ph
#juggles the placeholder while you type
def check(self, event):
if event.keysym == 'BackSpace':
if self.input and len(self.input) == 1:
self.input = self.__ph
self.icursor(0)
return 'break'
elif self.isholder:
if event.char:
self.input = ''
else:
return 'break'
用法示例:
usage example:
#__main__.py
import tkinter as tk
import widgets as ctk #custom tk
if __name__ == "__main__":
root = tk.Tk()
root.title("Placeholder Entry")
root.grid_columnconfigure(2, weight=1)
#init some data
entries = [] #for storing entry references
label_text = ['email', 'name']
entry_text = ['you@mail.com', 'John Smith']
#create form
for n, (label, placeholder) in enumerate(zip(label_text, entry_text)):
#make label
tk.Label(root, text=f'{label}: ', width=8, font='consolas 12 bold', anchor='w').grid(row=n, column=0, sticky='w')
#make entry
entries.append(ctk.PlaceholderEntry(root, placeholder, width=14, font='consolas 12 bold'))
entries[-1].grid(row=n, column=1, sticky='w')
#form submit function
def submit():
for l, e in zip(label_text, entries):
if e.input:
print(f'{l}: {e.input}')
#form submit button
tk.Button(root, text='submit', command=submit).grid(column=1, sticky='e')
root.mainloop()
这篇关于以程序方式向 tkinter Entry 小部件添加占位符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!