Se encadernado manipulador de eventos no Tkinter
-
02-07-2019 - |
Pergunta
Depois de um ligamento um método para um evento de um elemento Tkinter há uma maneira de obter o método de volta?
>>> 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.???
Solução
A chamada associada a fazer isso para a API tk C seria Get_GetCommandInfo que
Locais informações sobre o comando na estrutura Tcl_CmdInfo apontou para por infoPtr
No entanto, esta função não é usado em qualquer lugar _tkinter.c que é a ligação de tk utilizado por pitão calha Tkinter.py .
Por isso, é impossível obter a função limite de tkinter. É preciso lembrar que a função se.
Outras dicas
A maneira padrão de fazer isso em Tcl / Tk é trivial: você usar o mesmo comando de ligação, mas sem o argumento final.
bind .b <Button-1> doSomething
puts "the function is [bind .b <Button-1>]"
=> the function is doSomething
Você pode fazer algo semelhante com Tkinter mas os resultados são, infelizmente, não é tão útil:
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'
Obviamente, Tkinter está fazendo um monte de malabarismo abaixo das cobertas. Uma solução seria escrever um procedimento ajudante pouco que lembra isso para você:
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))
Você poderia usá-lo como este:
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>")
Quando eu executar o código acima eu recebo:
before, binding for <Button-1>: None
after, binding for <Button-1>: <function doSomething at 0xb7f2e79c>
Como uma advertência final, eu não uso Tkinter muito para que eu não tenho certeza quais são as ramificações de adicionar dinamicamente um atributo a uma instância de widget. Parece ser inofensivo, mas se não você sempre pode criar um dicionário global para manter o controle das ligações.
não parece ser ... porque não basta salvá-lo mesmo se você vai precisar dele, ou usar uma função não-anônimo?
Além disso, seu código não funciona como está escrito: funções lambda
só pode conter expressões, não declarações, então print
é um não-go (isso vai mudar em Python 3.0 quando print()
torna-se uma função)