Получить связанный обработчик событий в Tkinter
-
02-07-2019 - |
Вопрос
После привязки метода к событию элемента Tkinter есть ли способ вернуть метод?
>>> root = Tkinter.Tk()
>>> frame = Tkinter.Frame(root, width=100, height=100)
>>> frame.bind('<Button-1>', lambda e: pprint('Click')) # function needed
>>> frame.pack()
>>> bound_event_method = frame.???
Решение
Соответствующий вызов для этого для API tk C будет Get_GetCommandInfo который
Поместите информацию о команде в структуре TCL_CMDINFO, на которую указывает Infoptr
Однако эта функция нигде не используется. _tkinter.c какая привязка для tk используется Python Ткинтер.py.
Поэтому невозможно получить связанную функцию из tkinter.Вам нужно запомнить эту функцию самостоятельно.
Другие советы
Стандартный способ сделать это в Tcl/Tk тривиален:вы используете ту же команду связывания, но без последнего аргумента.
bind .b <Button-1> doSomething
puts "the function is [bind .b <Button-1>]"
=> the function is doSomething
Вы можете сделать что-то подобное с Tkinter, но результаты, к сожалению, будут не такими удобными:
e1.bind("<Button-1>",doSomething)
e1.bind("<Button-1>")
=> 'if {"[-1208974516doSomething %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y %D]" == "break"} break\n'
Очевидно, что Tkinter много занимается скрытой манипуляцией.Одним из решений было бы написать небольшую вспомогательную процедуру, которая запомнит это за вас:
def bindWidget(widget,event,func=None):
'''Set or retrieve the binding for an event on a widget'''
if not widget.__dict__.has_key("bindings"): widget.bindings=dict()
if func:
widget.bind(event,func)
widget.bindings[event] = func
else:
return(widget.bindings.setdefault(event,None))
Вы бы использовали это так:
e1=Entry()
print "before, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")
bindWidget(e1,"<Button-1>",doSomething)
print " after, binding for <Button-1>: %s" % bindWidget(e1,"<Button-1>")
Когда я запускаю приведенный выше код, я получаю:
before, binding for <Button-1>: None
after, binding for <Button-1>: <function doSomething at 0xb7f2e79c>
И последнее предостережение: я не часто использую Tkinter, поэтому не уверен, каковы последствия динамического добавления атрибута к экземпляру виджета.Кажется, это безобидно, но если нет, вы всегда можете создать глобальный словарь для отслеживания привязок.
Не кажется...почему бы просто не сохранить его самостоятельно, если он вам понадобится, или использовать неанонимную функцию?
Кроме того, ваш код не работает так, как написано: lambda
функции могут содержать только выражения, а не операторы, поэтому print
запрещен (это изменится в Python 3.0, когда print()
становится функцией).