The notion of "returning" values from callbacks doesn't make sense in the context of an event driven program. Callbacks are called as the result of an event, so there's nowhere to return a value to.

As a general rule of thumb, your callbacks should always call a function, rather than using functools.partial or lambda. Those two are fine when needed, but if you're using an object-oriented style of coding they are often unnecessary, and lead to code that is more difficult to maintain than it needs to be.

For example:

def compute():
    value = var.get()
    result = square(value)
    list_of_results.append(result)

button = Tk.Button(root, text='click', command = compute)
...

This becomes much easier, and you can avoid global variables, if you create your application as a class:

class App(...):
    ...
    def compute():
        ...
        result = self.square(self.var.get())
        self.results.append(result)
Answer from Bryan Oakley on Stack Overflow
Top answer
1 of 3
11

The notion of "returning" values from callbacks doesn't make sense in the context of an event driven program. Callbacks are called as the result of an event, so there's nowhere to return a value to.

As a general rule of thumb, your callbacks should always call a function, rather than using functools.partial or lambda. Those two are fine when needed, but if you're using an object-oriented style of coding they are often unnecessary, and lead to code that is more difficult to maintain than it needs to be.

For example:

def compute():
    value = var.get()
    result = square(value)
    list_of_results.append(result)

button = Tk.Button(root, text='click', command = compute)
...

This becomes much easier, and you can avoid global variables, if you create your application as a class:

class App(...):
    ...
    def compute():
        ...
        result = self.square(self.var.get())
        self.results.append(result)
2 of 3
9

Sorry for being 6 years late, but recently I figured out a good way to do this without making your code messy and hard to maintain. This is pretty much what DaveTheScientist has said, but I just want to expand on it a little. Usually, in Tkinter, if you want to have a button call a function, you do the following:

exampleButton = Button(root, text = 'Example', command = someFunc)

This will simply call someFunc whenever the button is pressed. If this function, however, takes arguments, you need to use lambdas and do something like this:

exampleButton = Button(root, text = 'Example', command = lambda: someFunc(arg1, arg2))

The above line of code will run someFunc and use the variables arg1 and arg2 as arguments for that function. Now, what you could do in a program where, a lot of the times, you would need the functions run by buttons to return values, is create a new function which is called by every button.

This function takes the function you want your button to run as a first argument, and that function's arguments afterwards.

def buttonpress(function, *args):
    value = function(*args)

Then when you create the button, you do:

exampleButton = Button(root, text = 'Example', command = lambda: buttonpress( someFunc, arg1, arg2 ))

This will run the given function (in this case, someFunc) and store the returned value in the value variable. It also has the advantage that you can use as many arguments as you want for the function your button runs.

🌐
YouTube
youtube.com › alan d moore codes
Tkinter Basics 2: Events and Callback Functions - YouTube
Learn how easy it is to use Tkinter and Python to build simple GUI applications with author Alan D Moore.Example code for this video can be found here: https...
Published   February 17, 2021
Views   4K
People also ask

What is the fundamental requirement for a Tkinter widget command
ANS: The command option expects a reference to a callable object (a function name) that, when invoked by the widget, takes zero arguments.
🌐
sqlpey.com
sqlpey.com › python › tkinter-passing-arguments-to-callbacks
Tkinter Callbacks: Passing Arguments to Widget Command Options
How can I pass an argument like 'hello' to a button's command function
ANS: Use a lambda function: command=lambda: my_function('hello'), or use functools.partial.
🌐
sqlpey.com
sqlpey.com › python › tkinter-passing-arguments-to-callbacks
Tkinter Callbacks: Passing Arguments to Widget Command Options
Why does button command=my_function('arg') not work as expected
ANS: Because my_function('arg') executes immediately during widget creation, assigning the return value of that call to the command, instead of the function itself.
🌐
sqlpey.com
sqlpey.com › python › tkinter-passing-arguments-to-callbacks
Tkinter Callbacks: Passing Arguments to Widget Command Options
🌐
TutorialsPoint
tutorialspoint.com › construct-button-callbacks-with-tkinter
Construct button callbacks with Tkinter
February 15, 2024 - When working with button callbacks, it's crucial to anticipate and handle potential errors gracefully. The use of try-except blocks is an effective strategy · import tkinter as tk from tkinter import messagebox def on_button_click(): try: print("Button clicked!") except Exception as e: messagebox.showerror("Error", f"An error occurred: {str(e)}") root = tk.Tk() root.title("Error Handling in Callbacks") root.geometry("720x250") button = tk.Button(root, text="Click Me", command=on_button_click) button.pack(pady=10) root.mainloop()
🌐
Quora
quora.com › How-can-I-define-a-sequence-of-callback-functions-in-Python-Tkinter
How to define a sequence of callback functions in Python Tkinter - Quora
Answer: You can create your buttons ... computable parameter(s). Button callback functions in TkInter have no parameters because they are going to be called from the Button event generating......
🌐
Python Tutorial
pythontutorial.net › home › tkinter tutorial › tkinter command binding
Tkinter Command Binding - Python Tutorial
April 3, 2025 - This requires assigning a callback function to a specific event. When the event occurs, the callback will be invoked automatically to handle the event. In Tkinter, some widgets allow you to associate a callback function with an event using the command binding.
Find elsewhere
🌐
Python.org
discuss.python.org › python help
Registering a validation callback in tkinter - Python Help - Discussions on Python.org
December 28, 2022 - Hello all, I’m learning tkinter which has been… interesting. I’m going off of the TkDocs tutorial because the tkinter documentation is intentionally sparse. There is one thing that I can’t seem to find a satisfying answer to in either though. ttk.Entry widgets support the validatecommand widget option (a keyword argument to the ttk.Entry class constructor), who’s value should be a callable to be invoked in the event that the content of the widget is changed by the user, etc.
🌐
sqlpey
sqlpey.com › python › tkinter-passing-arguments-to-callbacks
Tkinter Callbacks: Passing Arguments to Widget Command Options
October 29, 2025 - This example demonstrates a callback that alters the button’s own text upon being pressed, utilizing a global counter. import tkinter as tk i = 0 BUTTON_PHRASES = ("First Press", "Second Attempt", "Success", "Done") def update_button_text(): global i # Access the button object (if globally defined) or modify external state btn['text'] = BUTTON_PHRASES[i % len(BUTTON_PHRASES)] i = (i + 1) print(f"Counter: {i}") main_window = tk.Tk() main_window.title("Stateful Callback Demo") btn = tk.Button(main_window, text="Initial State", command=update_button_text) btn.pack(padx=20, pady=20) main_window.mainloop()
🌐
O'Reilly
oreilly.com › library › view › python-cookbook › 0596001673 › ch09s02.html
Avoiding lambda in Writing Callback Functions - Python Cookbook [Book]
July 19, 2002 - Writing a lot of callbacks that give customized arguments can look a little awkward with lambda, so this Command class gives an alternative syntax that looks nicer. For example: import Tkinter def hello(name): print "Hello", name root = Tk( ) # the lambda way of doing it: Button(root, text="Guido", command=lambda name="Guido": hello(name)).pack( ) # using the Command class: Button(root, text="Guido", command=Command(hello, "Guido")).pack( )
Authors   Alex MartelliDavid Ascher
Published   2002
Pages   608
🌐
Python Forum
python-forum.io › thread-12007.html
Unable to return value from callback function of a button in Python Tkinter
Hi Team I am trying to get the input written in an Entry box using Tkinter, But whenever I am trying to do so I am not getting the desired result..Instead a None is getting returned. Please help My code is given below from Tkinter import * class me...
🌐
sqlpey
sqlpey.com › python › tkinter-button-command-arguments-techniques
Tkinter Button Command Arguments: Techniques for Passing Data to Callbacks
October 29, 2025 - import tkinter as tk class ArgumentCarrier: def __init__(self, primary_value, secondary_value): self.primary = primary_value self.secondary = secondary_value def execute_callback(self): # Method accesses instance attributes when called by Tkinter combined = f"{self.primary} processed with {self.secondary}" print(combined) root = tk.Tk() # Create instances with specific initial arguments carrier1 = ArgumentCarrier(x=100, y="First Run") carrier2 = ArgumentCarrier(x=200, y="Second Run") # Button commands reference the instance method (no parentheses) btn1 = tk.Button(root, text="Run 1", command=carrier1.execute_callback) btn1.pack(pady=5) btn2 = tk.Button(root, text="Run 2", command=carrier2.execute_callback) btn2.pack(pady=5) # Arguments can be modified dynamically after creation carrier1.secondary = "Updated Run" root.mainloop()
Top answer
1 of 6
4

I cannot imagine any case and Im not sure at all if this answers your question but it maybe equivalent for what you are looking for:


The invoke method of the button seems pretty equivalent to me. So solution-1 would be:

import tkinter as tk

def hi():
    print('hello')

root = tk.Tk()
b = tk.Button(root, text='test', command=hi)
b.pack()

cmd = b.invoke
#cmd = lambda :b._do('invoke')
root.mainloop()

If this isnt what you looking for you could call the function in tcl level. Solution-2:

import tkinter as tk

def hi():
    print('hello')

root = tk.Tk()
b = tk.Button(root, text='test', command=hi)
b.pack()
cmd = lambda :root.tk.call(b['command'])
#cmd= lambda :root.tk.eval(b['command'])
cmd()
root.mainloop()

Solution 3, would be to return your function by invoke:

import tkinter as tk

def hi():
    print('hello')
    return hi

root = tk.Tk()
b = tk.Button(root, text='test', command=hi)
b.pack()
cmd = b.invoke()
print(cmd) #still a string but comparable
root.mainloop()
2 of 6
3

This is a more complex solution. It patches Misc._register, Misc.deletecommand and Misc.destroy to delete values from dict tkinterfuncs. In this example there are many print to check that values are added and removed from the dict.

import tkinter as tk

tk.tkinterfuncs = {} # name: func

def registertkinterfunc(name, func):
    """Register name in tkinterfuncs."""
    # print('registered', name, func)
    tk.tkinterfuncs[name] = func
    return name

def deletetkinterfunc(name):
    """Delete a registered func from tkinterfuncs."""
    # some funcs ('tkerror', 'exit') are registered outside Misc._register
    if name in tk.tkinterfuncs:
        del tk.tkinterfuncs[name]
        # print('delete', name, 'tkinterfuncs len:', len(tkinterfuncs))

def _register(self, func, subst=None, needcleanup=1):
    """Return a newly created Tcl function. If this
    function is called, the Python function FUNC will
    be executed. An optional function SUBST can
    be given which will be executed before FUNC."""
    name = original_register(self, func, subst, needcleanup)
    return registertkinterfunc(name, func)

def deletecommand(self, name):
    """Internal function.
    Delete the Tcl command provided in NAME."""
    original_deletecommand(self, name)
    deletetkinterfunc(name)

def destroy(self):
    """
    Delete all Tcl commands created for
    this widget in the Tcl interpreter.
    """
    if self._tclCommands is not None:
        for name in self._tclCommands:
            # print('- Tkinter: deleted command', name)
            self.tk.deletecommand(name)
            deletetkinterfunc(name)
        self._tclCommands = None

def getcommand(self, name):
    """
    Gets the command from the name.
    """
    return tk.tkinterfuncs[name]


original_register = tk.Misc.register
tk.Misc._register = tk.Misc.register = _register 
original_deletecommand = tk.Misc.deletecommand
tk.Misc.deletecommand = deletecommand
tk.Misc.destroy = destroy
tk.Misc.getcommand = getcommand

if __name__ == '__main__':
    def f():
        root.after(500, f)

    root = tk.Tk()
    root.after(500, f)
    but1 = tk.Button(root, text='button1', command=f)
    but1.pack()
    but2 = tk.Button(root, text='button2', command=f)
    but2.pack()
    but3 = tk.Button(root, text='button3', command=lambda: print(3))
    but3.pack()
    print(root.getcommand(but1['command']))
    print(root.getcommand(but2['command']))
    print(root.getcommand(but3['command']))
    but3['command'] = f
    print(root.getcommand(but3['command']))
    root.mainloop()
🌐
GitHub
github.com › python › cpython › issues › 66410
Tkinter: Don't stringify callback arguments · Issue #66410 · python/cpython
August 17, 2014 - gh-66410: Do not stringify arguments of Tkinter callback #98592
Author   serhiy-storchaka
🌐
Noobtomaster
noobtomaster.com › python-gui-tkinter › implementing-event-handlers-and-callbacks
Implementing event handlers and callbacks - Python GUI - tkinter
Start the event loop: Finally, start the event loop that constantly waits for events to occur and calls the respective event handlers or callbacks. ... The mainloop() function is a tkinter method that continuously listens for various events happening within the GUI.
🌐
15. The Menu widget
anzeljg.github.io › rin2 › book2 › 2405 › docs › tkinter › universal.html
26. Universal widget methods - Tkinter
Cancels a request for callback set up earlier .after(). The id argument is the result returned by the original .after() call. ... Requests that Tkinter call function func with arguments args next time the system is idle, that is, next time there are no events to be processed.
🌐
Universidad de Granada
ccia.ugr.es › mgsilvente › tkinterbook › tkinter-events-and-bindings.htm
Events and Bindings
In this example, we use the bind method of the frame widget to bind a callback function to an event called <Button-1>. Run this program and click in the window that appears. Each time you click, a message like “clicked at 44 63” is printed to the console window. Keyboard events are sent to the widget that currently owns the keyboard focus. You can use the focus_set method to move focus to a widget: ... from tkinter import * root = Tk() def key(event): print ("pressed", repr(event.char)) def callback(event): frame.focus_set() print ("clicked at", event.x, event.y) frame = Frame(root, width=100, height=100) frame.bind("<Key>", key) frame.bind("<Button-1>", callback) frame.pack() root.mainloop()
🌐
GitHub
github.com › Qirky › Troop › issues › 21
"Exception in Tkinter callback" · Issue #21 · Qirky/Troop
January 22, 2019 - Exception in Tkinter callback Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1550, in __call__ return self.func(*args) File "/Users/madskjeldgaard/Dropbox/scripts/sc/Troop/src/interface/conn_info.py", line 118, in store_data self.finish() File "/Users/madskjeldgaard/Dropbox/scripts/sc/Troop/src/interface/conn_info.py", line 90, in finish self.client.setup(**self.options) File "/Users/madskjeldgaard/Dropbox/scripts/sc/Troop/src/client.py", line 95, in setup self.lang = langtypes[lang](self.args) TypeError: __init__() takes 1 positional argument but 2 were given ·
Author   madskjeldgaard