Domanda

Dopo aver associato un metodo a un evento di un elemento Tkinter c'è un modo per riavere il metodo?

>>> 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.???
È stato utile?

Soluzione

La chiamata associata a farlo per l'API tk C sarebbe Get_GetCommandInfo quale

  

inserisce informazioni sul comando   nella struttura Tcl_CmdInfo appuntita   a da infoPtr

Tuttavia questa funzione non è utilizzata da nessuna parte in _tkinter.c che è l'associazione per tk utilizzata da python trough Tkinter.py .

Pertanto è impossibile estrarre la funzione associata da tkinter. Devi ricordare tu stesso quella funzione.

Altri suggerimenti

Il modo standard per farlo in Tcl / Tk è banale: usi lo stesso comando bind ma senza l'argomento finale.

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

Puoi fare qualcosa di simile con Tkinter ma, sfortunatamente, i risultati non sono così utilizzabili:

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'

Ovviamente, Tkinter sta facendo un sacco di giocoleria sotto le coperte. Una soluzione sarebbe quella di scrivere una piccola procedura di supporto che ricordi questo per te:

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 useresti in questo modo:

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 eseguo il codice precedente ottengo:

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

Come ultimo avvertimento, non uso molto Tkinter, quindi non sono sicuro di quali siano le conseguenze di aggiungere dinamicamente un attributo a un'istanza di widget. Sembra innocuo, ma in caso contrario puoi sempre creare un dizionario globale per tenere traccia dei collegamenti.

Non sembra essere ... perché non salvarlo da soli se ne hai bisogno o utilizzare una funzione non anonima?

Inoltre, il tuo codice non funziona come scritto: le funzioni lambda possono contenere solo espressioni, non istruzioni, quindi print non funziona (questo cambierà in Python 3.0 quando print () diventa una funzione).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top