如何在tkinter中为Entry添加占位符?

Pie*_*rce 14 python user-interface tkinter

我在tkinter中创建了一个登录窗口,它有两个Entry字段,第一个是Username,第二个是Password.

from tkinter import *

ui = Tk()

e1 = Entry(ui)
#i need a placeholder "Username" in the above entry field
e1.pack()

ui.mainloop()
Run Code Online (Sandbox Code Playgroud)

我想要一个名为"用户名"的占位符Entry,但如果你点击里面,文字应该消失.

Nae*_*Nae 12

您可以创建一个继承自Entry下面的类:

import tkinter as tk

class EntryWithPlaceholder(tk.Entry):
    def __init__(self, master=None, placeholder="PLACEHOLDER", color='grey'):
        super().__init__(master)

        self.placeholder = placeholder
        self.placeholder_color = color
        self.default_fg_color = self['fg']

        self.bind("<FocusIn>", self.foc_in)
        self.bind("<FocusOut>", self.foc_out)

        self.put_placeholder()

    def put_placeholder(self):
        self.insert(0, self.placeholder)
        self['fg'] = self.placeholder_color

    def foc_in(self, *args):
        if self['fg'] == self.placeholder_color:
            self.delete('0', 'end')
            self['fg'] = self.default_fg_color

    def foc_out(self, *args):
        if not self.get():
            self.put_placeholder()

if __name__ == "__main__": 
    root = tk.Tk() 
    username = EntryWithPlaceholder(root, "username")
    password = EntryWithPlaceholder(root, "password", 'blue')
    username.pack()
    password.pack()  
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)

  • 另外,在“__init__”上接受“*args”和“**kwargs”可能是明智的,尽管您可能需要在“FocusIn”和“FocusOut”事件中处理“textvariable”关键字以防止占位符被发送到“StringVar” (2认同)

Dan*_*mad 11

这适用于您想要的任何占位符。

from tkinter import *
root = Tk()

my_entry = Entry(root, width=50)
my_entry.pack()
my_entry.insert(0, "Place Holder")
my_entry.configure(state=DISABLED)

def on_click(event):
    my_entry.configure(state=NORMAL)
    my_entry.delete(0, END)

    # make the callback only work once
    my_entry.unbind('<Button-1>', on_click_id)

on_click_id = my_entry.bind('<Button-1>', on_click)

root.mainloop()
Run Code Online (Sandbox Code Playgroud)


Ste*_*Lin 10

您需要为此条目设置默认值.像这样:

from tkinter import *

ui = Tk()

e1 = Entry(ui)
e1.insert(0, 'username')
e1.pack()

ui.mainloop()
Run Code Online (Sandbox Code Playgroud)

然后,如果要在单击条目时删除内容,则必须使用事件处理程序方法绑定鼠标单击事件以更新此条目的内容.这是给你的链接.

  • 您应该绑定到"<FocusIn>",而不是绑定到单击,因为可以通过键盘将焦点切换到条目小部件.如果你真的展示了如何做到这一点,你的答案会好一点. (8认同)
  • 这是根据布莱恩(Bryan)的建议为将来的读者准备的一个简单的划线:`e1.bind(“ &lt;FocusIn&gt;”,lambda args:e1.delete('0','end'))`。 (3认同)

Art*_*ião 5

我的解决方案是子类化tk.Entry并控制内容和颜色,将<FocusIn><FocusOut>事件绑定到根据需要填充和清除文本的方法。这是行为:

在此输入图像描述

这里是完整的示例代码:

import tkinter as tk

class PlaceholderEntry(tk.Entry):
    def __init__(self, master=None, placeholder='', cnf={}, fg='black',
                 fg_placeholder='grey50', *args, **kw):
        super().__init__(master=None, cnf={}, bg='white', *args, **kw)
        self.fg = fg
        self.fg_placeholder = fg_placeholder
        self.placeholder = placeholder
        self.bind('<FocusOut>', lambda event: self.fill_placeholder())
        self.bind('<FocusIn>', lambda event: self.clear_box())
        self.fill_placeholder()

    def clear_box(self):
        if not self.get() and super().get():
            self.config(fg=self.fg)
            self.delete(0, tk.END)

    def fill_placeholder(self):
        if not super().get():
            self.config(fg=self.fg_placeholder)
            self.insert(0, self.placeholder)
    
    def get(self):
        content = super().get()
        if content == self.placeholder:
            return ''
        return content

class App(tk.Frame):
    def __init__(self, master=None):
        self.root = master
        super().__init__(master, borderwidth=0, relief=tk.RAISED)
        
        self.root.title('Placeholder example')
        self.pack_propagate(False)
        self.pack()
        
        self.entry = PlaceholderEntry(self.root, placeholder='This text is a placeholder')
        self.entry.pack()
        
        self.btn = tk.Button(self.root, text='Nothing', highlightcolor='cyan')
        self.btn.pack()
        

root = tk.Tk()
app = App(master=root)

app.root.mainloop()
Run Code Online (Sandbox Code Playgroud)