web-dev-qa-db-fra.com

Comment passer un argument au gestionnaire d'événements dans tkinter?

widget.bind('<Button-1>',callback)   # binding 

def callback(self,event)
    #do something

Je dois passer un argument à callback(). L'argument est un objet du dictionnaire.

21
sag

Vous pouvez utiliser lambda pour définir une fonction anonyme, telle que:

data={"one": 1, "two": 2}

widget.bind("<ButtonPress-1>", lambda event, arg=data: self.on_mouse_down(event, arg))

Notez que la arg passée devient juste un argument normal que vous utilisez comme tous les autres arguments:

def on_mouse_down(self, event, arg):
    print(arg)
40
Bryan Oakley

Qu'en est-il de

import functools
def callback(self, event, param):
    pass
arg = 123
widget.bind("", functools.partial(callback, param=arg))
9
Philipp

Je pense que dans la plupart des cas, vous n'avez pas besoin d'argument pour un rappel car ce dernier peut être une méthode d'instance pouvant accéder aux membres de l'instance:

from Tkinter import *

class MyObj:
    def __init__(self, arg):
        self.arg = arg

    def callback(self, event):
        print self.arg

obj = MyObj('I am Obj')
root = Tk()
btn=Button(root, text="Click")
btn.bind('<Button-1>', obj.callback)
btn.pack()
root.mainloop()

Mais je pense que la solution functools proposée par Philipp est aussi très gentille 

4
luc

Transmettez la fonction de rappel à l'instance et appelez-la à partir de la méthode d'instance.

from tkinter import *

class MyClass:

    def __init__(self, my_callback, message):
        self.my_callback = my_callback
        self.message = message

    def callback(self, event):
        self.my_callback(self)

def my_callback(o):
    print(o.message)


obj = MyClass(my_callback, "I am instance of MyClass")

root = Tk()

btn=Button(root, text="Click")
btn.bind('<Button-1>', obj.callback)
btn.pack()
1
Iordanov K.

Vous pouvez également fournir des arguments à une fonction de rappel d’un widget, étant donné que ce widget est défini comme faisant partie d’une définition de classe, c'est-à-dire considérons ce petit programme python 2.7 (sans les parties responsable de l'exécution du programme):

import Tkinter as tk #To be able to get "tk.Button" safely
from Tkinter import *

class EXAMPLE(Frame):
    def __init__(self,master=None):
        Frame.__init__(self,master)

        #make the widgets appear to a grid of size = 2 X 2
        for row in range(2):
            self.grid_rowconfigure(row,minsize=20)
        for col in range(2):
            self.grid_columnconfigure(col,minsize=20)

        #Call our METHOD OF INTEREST
        self.AnyMethod()

    #This is our method of interest
    def AnyMethod(self):
        #arguments to be supplied
        self.arg1 = 'I am 1st argument'
        self.arg2 = 'I am 2nd argument'
        self.arg3 = 'I am 3rd argument'

        #Draw the widget, & supply its callback method
        self.widgetname=tk.Button(self.master,text="My Button",command=self.method_callback)
        self.widgetname.grid(row=0,column=0)

    #create a so-called 'Shell method' to swallow the REAL callback function
    def method_callback(self):
        func_callback(self.arg1,self.arg2,self.arg3)

#Define the REAL callback function in the Module's scope
def func_callback(arg1,arg2,arg3):
    print arg1
    print arg2
    print arg3

NOTE QUE les arguments fournis doivent être traités avec self. 

0
Serag Hassouna

Voici la solution la plus simple et la plus facile à lire:

widget.bind('<Button-1>', callback2)

def callback(self, event, custom_arg=None): #change "None" to whatever you want the default value to be
    #do something

def callback2(self, event):
    callback(event, custom_arg=something_you_set) #set custom_arg to whatever you want it to be when Button-1 is pressed
0
Gabriel Staples