This should work:
...
btnaText='ButtonA'
btna = Button(root, text = btnaText, command = lambda: sayHi(btnaText))
btna.pack()
For more information take a look at Tkinter Callbacks
Answer from Ocaso Protal on Stack OverflowThis should work:
...
btnaText='ButtonA'
btna = Button(root, text = btnaText, command = lambda: sayHi(btnaText))
btna.pack()
For more information take a look at Tkinter Callbacks
text is not a function in your case. Just have it as:
value = 'ButtonA'
btna = Button(root, text = value, command = lambda: sayHi(value))
And you will get that working.
Videos
What is the fundamental requirement for a Tkinter widget command
Does the button command callback return values
Is using lambda cleaner than functools partial
This can be done using a lambda, like so:
button = Tk.Button(master=frame, text='press', command= lambda: action(someNumber))
This is a simple way to bind the argument without an explicit wrapper method or modifying the original action.
This can also be done by using partial from the standard library functools, like this:
from functools import partial
#(...)
action_with_arg = partial(action, arg)
button = Tk.Button(master=frame, text='press', command=action_with_arg)
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)
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.
Kevin's answer is correct for the general problem of including data along with the event instance, but is redundant when the extra data is the widget causing the event. Events have up to 17 attributes, including .widget, the widget that was the source of the event. (I strongly recommend the tkinter reference that includes the above link.) The following prints the contents of the entry widget when return is hit.
from tkinter import *
def checkPassword(event):
print(event.widget.get())
window = Tk()
Entry = Entry(window)
Entry.bind("<KeyRelease-Return>", checkPassword)
Entry.pack()
window.mainloop()
Your second attempt was close, but since checkPassword isn't a class method, you shouldn't be prefixing it with self..
def checkPassword(event, some_value_you_want):
# do stuff
Entry.bind("<KeyRelease-Return>", lambda event: checkPassword(event, name_of_your_entry_widget))
You can use lambda to define an anonymous function, such as:
data={"one": 1, "two": 2}
widget.bind("<ButtonPress-1>", lambda event, arg=data: self.on_mouse_down(event, arg))
Note that the arg passed in becomes just a normal argument that you use just like all other arguments:
def on_mouse_down(self, event, arg):
print(arg)
What about
import functools
def callback(self, event, param):
pass
arg = 123
widget.bind("", functools.partial(callback, param=arg))