Reputation: 3855
I have a tkinter GUI with an entry field and a validation button. I'd like to call the same function when I press a key in the entry, or when I click the button.
The problem is, with the bind method on the entry, I need a "self" argument for my function to work, but not with the button.
Here is the simplified code:
from tkinter import *
import tkinter.messagebox
import tkinter.filedialog
def function():
print("Here are some words.")
my_window = Tk()
text = StringVar()
input_widget = Entry(my_window, textvariable = text) #We create an input widget.
input_widget.bind("<Return>", function)
benjamin = Button(my_window, text ='Print', command = function) #We create another widget, a
# button that sends the same function as pressing <Return> key.
input_widget.grid(row = 0, column = 0) #We use grid to place our widgets.
benjamin.grid(row = 0, column = 1)
my_window.mainloop()
With this code, when I use the button, no problem, it prints, but when I use the bind, it returns:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\"blablabla"\tkinter\__init__.py, line 1533, in __call__
return self.func(*args)
TypeError: function() takes 0 positionnal arguments but 1 was given
I can make it work by calling two functions one for the button, and another for the entry with a self argument:
def function2(self):
print("It works with this function.")
Is there any way to make both .bind
and command
share the the same function?
Upvotes: 1
Views: 2269
Reputation: 2115
Add this to your binding:
input_widget.bind("<Return>", lambda event: function())
Event bindings all require an event parameter which is automatically passed to the function. By using a lambda with the parameter event; you can take in this "event" variable and basically discard it and do whatever is in function()
Upvotes: 0
Reputation: 76234
You could write your function so that it takes any number of arguments:
def function(*args):
#args is now a tuple containing every argument sent to this function
print("Here are some words.")
Now you can successfully call the function with 0, 1, or any other number of arguments.
Alternatively, you could keep your function as it is, and use a lambda to discard the unused self
value:
input_widget.bind("<Return>", lambda x: function())
Upvotes: 1