Pregunta

Después de vincular un método a un evento de un elemento Tkinter, ¿hay alguna forma de recuperar el método?

>>> 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.???
¿Fue útil?

Solución

La llamada asociada para hacer eso para el tk C API sería Get_GetCommandInfo que

  

coloca información sobre el comando   en la estructura Tcl_CmdInfo señalada   a por infoPtr

Sin embargo, esta función no se utiliza en ningún lugar en _tkinter.c que es el enlace para tk utilizado por python a través de Tkinter.py .

Por lo tanto, es imposible obtener la función enlazada fuera de tkinter. Necesita recordar esa función usted mismo.

Otros consejos

La forma estándar de hacer esto en Tcl / Tk es trivial: usa el mismo comando de enlace pero sin el argumento final.

bind .b <Button-1> doSomething
puts "the function is [bind .b <Button-1>]"
=> the function is doSomething

Puedes hacer algo similar con Tkinter pero, desafortunadamente, los resultados no son tan fáciles de usar:

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á haciendo muchos malabares debajo de las cubiertas. Una solución sería escribir un pequeño procedimiento de ayuda que lo recuerde:

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))

Lo usarías así:

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>")

Cuando ejecuto el código anterior, obtengo:

before, binding for <Button-1>: None
 after, binding for <Button-1>: <function doSomething at 0xb7f2e79c>

Como advertencia final, no uso mucho Tkinter, así que no estoy seguro de cuáles son las ramificaciones de agregar dinámicamente un atributo a una instancia de widget. Parece ser inofensivo, pero si no, siempre puedes crear un diccionario global para realizar un seguimiento de los enlaces.

No parece ser ... ¿por qué no solo guardarlo si lo vas a necesitar, o usar una función no anónima?

Además, su código no funciona como está escrito: las funciones lambda solo pueden contener expresiones, no declaraciones, por lo que print es un no-go (esto cambiará en Python 3.0 cuando print () se convierte en una función).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top