Binding <Return> to a button does not work properly
I connected the <Return> event with the button, believing that this would cause command be fired after pressing Enter :
Button(self.f, text="Print", command=self.Printer).pack(side=RIGHT, padx=10, pady=10) self.button1 = Button(self.f, text="search", command=self.search) self.button1.bind('<Return>', self.search) self.button1.pack(side=RIGHT, padx=10, pady=10) But he does nothing. What to do for self.search to start when I press Enter ?
Your code looks good, but note that the focus should be on the button if you want Return call self.search() . You can change the focus from widget to widget by pressing Tab . The widget in focus is outlined by a thin black line. You may need to press Tab one or more times to move the focus to the button before pressing Return .
If you want Return work anywhere in the GUI, change
self.button1.bind('<Return>', self.search) to
root.bind('<Return>', self.search) where root = tk.Tk() .
For example, compare button.bind with master.bind in the code below:
import Tkinter as tk class SimpleApp(object): def __init__(self, master, **kwargs): title = kwargs.pop('title') frame = tk.Frame(master, **kwargs) frame.grid() button = tk.Button(frame, text = 'search', command = self.search) button.grid() button.bind('<Return>', self.search) # uncomment if you want `<Return>` bound everywhere. # master.bind('<Return>', self.search) def search(self,*args): print('searching...') def basic(): root = tk.Tk() app = SimpleApp(root, title = 'Hello, world') root.mainloop() basic() Alternatively you can use
button.bind('<Return>', self.search) button.focus() Performing this, pressing Return calls self.search() only when the button has focus, but the button starts to focus when the application starts.
Regarding the use of *args and **kwargs :
**kwargs allows you to pass arbitrary keyword arguments to __init__ .
When **kwargs used in a function definition as follows:
def __init__(self, master, **kwargs): and we create an instance of SimpleApp as follows:
app = SimpleApp(root, title = 'Hello, world') then Python sets kwargs to a dict containing the keyword arguments, for example. {'title':'Hello, world'} . Note that **kwargs is Python syntax that can only be used in function definitions and function calls (see below), but kwargs itself is just a dict.
kwargs then passed to Frame :
frame = tk.Frame(master, **kwargs) Now that ** kwargs is used in a function call, the key-value pairs in kwargs dict are expanded, so the above function call is equivalent
frame = tk.Frame(master, title = 'Hello, world') Since Frame can take multiple keyword arguments, and I donโt know all of them and donโt want to list them, itโs useful to use **kwargs . Also note that even if new keyword arguments were added to Frame at some later date, my code will still work, whereas if I clearly articulated the keywords, then my code will not automatically โupdateโ, if valid keywords Frame change.
*args , similarly, allows you to include arbitrary positional arguments in search :
def search(self,*args): Python sets args to a list containing all positional arguments sent to search when search is called.
I used * args here because self.search is called with no arguments or one argument.
When you speak
button = tk.Button(frame, text = 'search', command = self.search) self.search() is called with no arguments when the button is clicked. But when you say
button.bind('<Return>', self.search) self.search(event) is called with one argument when the Return key is pressed. event is a Tkinter.Event that has attributes (time, state, type, widget, x, y, etc.) that allow you to learn more about what happened.
Another, perhaps better way to determine search would be
def search(self, event = None): ... It would be clear that search can be passed with 0 or 1 arguments, and not just with an arbitrary number of arguments. It would also provide easy access to the event if the event was sent to search .
Link: