How to pass an argument to event handler in tkinter?

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

def callback(self,event)
    #do something

I need to pass an argument to callback() . The argument is a dictionary object.

7 Answers

Here is an entry on this from the New Mexico Tech Tkinter 8.5 Reference (https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/extra-args.html) ‌‌‌‌‍‬‍‌‌‌‌‍‬‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‍‬‬‍‌‌‌‌‍‌‌‌‌‌‍‬‬‌‌‌‌‌‍‬‍‌‌‌‌‍‬‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‍‬‬‍‌‌‌‌‍‌‌‌‌‌‍‬‬‌

‌‌‌‌‍‬‍‌‌‌‌‍‬‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‍‬‬‍‌‌‌‌‍‌‌‌‌‌‍‬‬‌

This way allows you to add as many arguments as you need:

‌‌‌‌‍‬‍‌‌‌‌‍‬‬‍‌‌‌‌‍‬‌‬‌‌‌‌‍‬‌‬‌‌‌‌‍‬‍‍‌‌‌‌‍‌‬‌‌‌‌‍‬‬‍‌‌‌‌‍‌‌‌‌‌‍‬‬‌

54.7. The extra arguments trick

Sometimes you would like to pass other arguments to a handler besides the event.

Here is an example. Suppose your application has an array of ten checkbuttons whose >widgets are stored in a list self.cbList, indexed by the checkbutton number in >range(10).

Suppose further that you want to write one handler named .__cbHandler for >events in all ten of these checkbuttons. The handler can get the actual Checkbutton >widget that triggered it by referring to the .widget attribute of the Event object that >gets passed in, but how does it find out that checkbutton's index in self.cbList?

It would be nice to write our handler with an extra argument for the checkbutton number, >something like this:

def __cbHandler(self, event, cbNumber):

But event handlers are passed only one argument, the event. So we can't use the function >above because of a mismatch in the number of arguments.

Fortunately, Python's ability to provide default values for function arguments gives us >a way out. Have a look at this code:

def __createWidgets(self):
    …
    self.cbList = []    # Create the checkbutton list
    for i in range(10):
        cb = tk.Checkbutton(self, …)
        self.cbList.append(cb)
        cb.grid( row=1, column=i)
        def handler(event, self=self, i=i):   1
            return self.__cbHandler(event, i)
        cb.bind('<Button-1>', handler)
    …
def __cbHandler(self, event, cbNumber):
    …

These lines define a new function handler that expects three arguments. The first >argument is the Event object passed to all event handlers, and the second and third >arguments will be set to their default values—the extra arguments we need to pass it.

This technique can be extended to supply any number of additional arguments to >handlers.

Pass the callback function to the instance and call it from the instance method.

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