【问题标题】:Create background text in Entry Tkinter [duplicate]在Entry Tkinter中创建背景文本[重复]
【发布时间】:2021-02-07 10:16:34
【问题描述】:

你能帮我在我的条目中显示一个文本,点击条目后消失吗?

为此,我在条目中有以下示例,其中包含文本“搜索”。我希望在我的条目中准确显示此文本。

非常感谢!

【问题讨论】:

标签: python tkinter


【解决方案1】:

您要查找的内容称为占位符。不幸的是,占位符上没有 tkinter 的默认选项,但是一个简单的占位符看起来像:

import tkinter as tk

root = tk.Tk()

placeholder = 'Your text here'

def erase(event=None):
    if e.get() == placeholder:
        e.delete(0,'end')
def add(event=None):
    if e.get() == '':
        e.insert(0,placeholder)

e = tk.Entry(root)
e.pack(padx=10,pady=10)

dummy = tk.Entry(root) #dummy widget just to see other widget lose focus
dummy.pack(padx=10,pady=10)

add()
e.bind('<FocusIn>',erase)
e.bind('<FocusOut>',add)

root.mainloop()

但是这段代码有很多缺点,因为如果您希望处理更多数据,输入方法将无法正常工作,所以我更喜欢做的是创建一个类并使用它,而不是使用默认的Entry 类。

这是我为类似情况编写的代码,我不声称这是多么完美,但这可以完成你的工作。

import tkinter as tk
from tkinter import ttk as ttk

class PlaceholderEntry(ttk.Entry):
    '''
    Custom modern Placeholder Entry box, takes positional argument master and placeholder along with\n
    textcolor(default being black) and placeholdercolor(default being grey).\n
    Use acquire() for getting output from entry widget\n
    Use shove() for inserting into entry widget\n
    Use remove() for deleting from entry widget\n
    Use length() for getting the length of text in the widget\n
    BUG 1: Possible bugs with binding to this class\n
    BUG 2: Anomalous behaviour with config or configure method
    '''
    def __init__(self, master, placeholder,textcolor='black',placeholdercolor='grey', **kwargs):
        self.text = placeholder
        self.__has_placeholder = False # placeholder flag
        self.placeholdercolor = placeholdercolor
        self.textcolor = textcolor

        # style for ttk widget
        self.s = ttk.Style()

        # init entry box
        ttk.Entry.__init__(self, master, style='my.TEntry', **kwargs)
        self.s.configure('my.TEntry',forground=self.placeholdercolor)

        # add placeholder if box empty
        self._add()

        # bindings of the widget
        self.bind('<FocusIn>', self._clear)
        self.bind('<FocusOut>', self._add)
        self.bind_all('<Key>', self._normal)
        self.bind_all('<Button-1>', self._cursor)

    def _clear(self, *args): # method to remove the placeholder
        if self.get() == self.text and self.__has_placeholder:  # remove placeholder when focus gain
            self.delete(0, tk.END)
            self.s.configure('my.TEntry', foreground='black',
                             font=(0, 0, 'normal'))
            self.__has_placeholder = False #set flag to false

    def _add(self, *args): # method to add placeholder
        if self.get() == '' and not self.__has_placeholder:  # if no text add placeholder
            self.s.configure('my.TEntry', foreground=self.placeholdercolor,
                             font=(0, 0, 'bold'))
            self.insert(0, self.text)  # insert placeholder
            self.icursor(0)  # move insertion cursor to start of entrybox
            self.__has_placeholder = True #set flag to true

    def _normal(self, *args): #method to set the text to normal properties
        self._add()  # if empty add placeholder
        if self.get() == self.text and self.__has_placeholder:  # clear the placeholder if starts typing
            self.bind('<Key>', self._clear)
            self.icursor(-1)  # keep insertion cursor to the end
        else:
            self.s.configure('my.TEntry', foreground=self.textcolor,
                         font=(0, 0, 'normal'))  # set normal font

    def acquire(self):  
        """Custom method to get the text"""
        if self.get() == self.text and self.__has_placeholder:
            return 'None'
        else:
            return self.get()

    def shove(self, index, string):  
        """Custom method to insert text into entry"""
        self._clear()
        self.insert(index, string)

    def remove(self, first, last):  
        """Custom method to remove text from entry"""
        if self.get() != self.text:
            self.delete(first, last)
            self._add()
        elif self.acquire() == self.text and not self.__has_placeholder:
            self.delete(first, last)
            self._add()

    def length(self):
        """Custom method to get the length of text in the entry widget"""
        if self.get() == self.text and self.__has_placeholder:
            return 0
        else:
            return len(self.get())

    def _cursor(self, *args):  # method to not allow user to move cursor when placeholder exists
        if self.get() == self.text and self.__has_placeholder:
            self.icursor(0)

#usage
if __name__ == '__main__':
    root = tk.Tk()
    
    e = PlaceholderEntry(root,placeholder='Your text')
    e.pack(padx=10,pady=10)
    
    dummy = tk.Entry(root) #dummy widget just to see other widget lose focus
    dummy.pack(padx=10,pady=10)
    
    root.mainloop()

虽然我建议您在了解幕后情况后使用后一个示例。

PS:- 在创建多个类的实例时,带有类的示例是错误的。

【讨论】:

  • 类怎么会扩展tk.Entry,但在里面使用ttk.Entry.__init__(...)
  • @acw1668 导入错误,已更新。
  • @CoolCloud 问题仍然存在 class PlaceholderEntry(tk.Entry):ttk.Entry.__init__(self, master, style='my.TEntry', **kwargs)
  • @Atlas435 有什么问题?你试过这个吗?它对我有用。我也在导入ttk
  • 好吧,我只是好奇你为什么要costumize tk.Entryinitialize ttk.Entry 这是出于某种原因吗?
猜你喜欢
  • 1970-01-01
  • 2020-10-13
  • 1970-01-01
  • 2016-06-20
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
相关资源
最近更新 更多