Базовый запрос относительно bindtags в tkinter
В приведенном примере из этого поста упоминалось, что если используются биндтеги по умолчанию, то значение события не будет видно внутри определения (будет задержка на единицу).
Было дано некоторое объяснение относительно привязки к классу.
Я новичок, поэтому хотел бы понять подробную причину.
Может кто-нибудь, пожалуйста, объяснить, почему это не работало в первом случае и работало во втором (когда порядок bindtags изменен).
import Tkinter
def OnKeyPress(event):
value = event.widget.get()
string="value of %s is '%s'" % (event.widget._name, value)
status.configure(text=string)
root = Tkinter.Tk()
entry1 = Tkinter.Entry(root, name="entry1")
entry2 = Tkinter.Entry(root, name="entry2")
entry3 = Tkinter.Entry(root, name="entry3")
entry1.bindtags(('.entry1', 'Entry', '.', 'all'))
entry2.bindtags(('Entry', '.entry1', '.', 'all'))
entry3.bindtags(('.entry1','Entry','post-class-bindings', '.', 'all'))
btlabel1 = Tkinter.Label(text="bindtags: %s" % " ".join(entry1.bindtags()))
btlabel2 = Tkinter.Label(text="bindtags: %s" % " ".join(entry2.bindtags()))
btlabel3 = Tkinter.Label(text="bindtags: %s" % " ".join(entry3.bindtags()))
status = Tkinter.Label(anchor="w")
entry1.grid(row=0,column=0)
btlabel1.grid(row=0,column=1, padx=10, sticky="w")
entry2.grid(row=1,column=0)
btlabel2.grid(row=1,column=1, padx=10, sticky="w")
entry3.grid(row=2,column=0)
btlabel3.grid(row=2,column=1, padx=10)
status.grid(row=3, columnspan=2, sticky="w")
entry1.bind("<KeyPress>", OnKeyPress)
entry2.bind("<KeyPress>", OnKeyPress)
entry3.bind_class("post-class-bindings", "<KeyPress>", OnKeyPress)
root.mainloop()
Переведено автоматически
Ответ 1
Когда вы выполняете привязку к виджету, вы на самом деле не привязываетесь к виджету как таковому. Когда вы выполняете mywidget.bind(...)
, на самом деле происходит то, что привязка связана с тегом bind с тем же именем, что и у виджета.
При обнаружении события Tkinter сначала определяет, какой виджет перехватил событие. У этого виджета будет список из нуля или более (по умолчанию: четырех) связанных с ним тегов bind. Tkinter проверит каждый тег, чтобы увидеть, есть ли привязка, соответствующая событию. Если он найдет один, он выполнит привязку, а затем перейдет к следующему тегу, пока не закончатся теги или одна из связанных функций не вернет строку "break"
.
Последовательность выглядит примерно так:
- Вы нажимаете клавишу "x". На этом этапе "x" нигде не был вставлен
- Tkinter получает теги привязки для виджета, который имеет фокус клавиатуры.
- По умолчанию первым тегом привязки является сам виджет. Есть ли привязка к этому тегу? Если да, выполните его. Например, вы можете распечатать содержимое виджета. Поскольку другие привязки еще не запущены, "x" не будет частью содержимого.
- Если связанная функция возвращает результат
"break"
, обработка событий больше не выполняется. "X" не будет вставлен в виджет. - Если виджет не вернул результат
"break"
, tkinter переходит к следующему тегу привязки. - По умолчанию следующим тегом привязки является класс widget. Существует ли привязка к классу, соответствующая этому событию (нажатию буквы "x")?
- В этом случае у класса действительно есть привязка для этого события, которая заключается в фактической вставке "x" в виджет. До этого момента "x" все еще не был вставлен в виджет. Однако после этой привязки, если вы распечатаете содержимое, вы увидите "x"
- Обработка продолжается таким образом до тех пор, пока не будут обработаны все теги привязки.
Судя по продолжающемуся обсуждению в разделе комментариев, похоже, что это все еще неясно. Я постараюсь сделать это как можно проще:
Это привязка класса, которая копирует символ из объекта события в памяти в виджет и, таким образом, вызывает его отображение на экране. До срабатывания привязки класса символ не будет отображаться в виджете. После привязки класса он будет в виджете.