Возврат пустого поля ввода tk в предыдущее состояние при удалении от

#python #tkinter

#python #tkinter

Вопрос:

В настоящее время я разрабатываю свою первую программу на Python, систему бронирования с использованием tkinter. У меня есть экран создания учетной записи клиента, который использует несколько полей ввода. При нажатии на поле ввода вызывается следующая привязка ключа, чтобы очистить поле ввода от его инструкции (т. Е. «введите имя»)

 def entry_click(event):
  if "enter" in event.widget.get():
     event.widget.delete(0, "end")
     event.widget.insert(0, "")
     event.widget.configure(fg="white")

#example Entry fields
new_name = Entry(root)
new_name.insert(0, "enter name")
new_name.bind('<FocusIn>', entry_click)
new_name.bind('<FocusOut>', entry_focusout)

new_email = Entry(root)
new_email.insert(0, "enter email")
new_email.bind('<FocusIn>', entry_click)
new_email.bind('<FocusOut>', entry_focusout)
  

В аналогичном ключе я ищу способ создать универсальное событие, в котором соответствующий текст для этого уникального поля ввода возвращается в исходное состояние (т. Е. «введите имя» или «введите адрес электронной почты»), если поле пусто при удалении от.

 def entry_focusout():
if not event.widget.get():
   event.widget.insert(fg="grey")
   event.widget.insert(0, #[appropriate text here])
  

Как бы я мог это сделать?
Большое спасибо.

Комментарии:

1. Мне нужна та же функция, чтобы также работать для new_email, например, где дело было бы .insert(0, «введите адрес электронной почты») — текст, который необходимо вернуть в запись, не является универсальным и должен отличаться для каждой записи

Ответ №1:

Просто добавьте аргумент к вашему entry_focusout событию и привяжитесь к Entry виджетам с помощью лямбда-функции.

 from tkinter import *

root = Tk()

def entry_click(event):
  if event.widget["foreground"] == "grey":
     event.widget.delete(0, "end")
     event.widget.insert(0, "")
     event.widget.configure(fg="black")

def entry_focusout(event, msg):
    if not event.widget.get():
       event.widget.configure(fg="grey") #you had a typo here
       event.widget.insert(0, msg)

new_name = Entry(root,fg="grey")
new_name.insert(0, "enter name")
new_name.bind('<FocusIn>', entry_click)
new_name.bind('<FocusOut>', lambda e: entry_focusout(e, "enter name"))

new_email = Entry(root,fg="grey")
new_email.insert(0, "enter email")
new_email.bind('<FocusIn>', entry_click)
new_email.bind('<FocusOut>', lambda e: entry_focusout(e, "enter email"))

new_name.pack()
new_email.pack()

root.mainloop()
  

Комментарии:

1. Это if "enter" in ... может привести к ошибкам , Entry могло быть 'enter' как часть данных.

2. Да, но это его логика, и я оставляю ее как есть. Для меня я, вероятно, буду использовать if event.widget.get() == "enter name"

3. Вы правы, мой комментарий должен был перейти к вопросу. Спасибо за простое решение.

Ответ №2:

Вопрос: Вернуть пустое tk.Entry поле в предыдущее состояние при удалении

Следующее является OOP универсальным решением.
Спасибо @Henry Yik за if event.widget["foreground"] == "grey": часть.

 class EntryInstruction(tk.Entry):
    def __init__(self, parent, instruction=None):
        super().__init__(parent)
        self.instruction = instruction

        self.focus_out(None)
        self.bind('<FocusIn>', self.focus_in)
        self.bind('<FocusOut>', self.focus_out)

    def focus_in(self, event):
        if self["foreground"] == "grey":
            self.delete(0, "end")
            self.configure(fg="black")

    def focus_out(self, event):
        if not self.get():
            self.configure(fg="grey")
            self.insert(0, self.instruction)
  

Использование:

 class App(tk.Tk):
    def __init__(self):
        super().__init__()

        entry = EntryInstruction(self, '<enter name>')
        entry.grid(row=0, column=0)

        entry = EntryInstruction(self, '<enter email>')
        entry.grid(row=1, column=0)

if __name__ == "__main__":
    App().mainloop()
  

Протестировано с Python: 3.5