I bound the event <Return>
to a Button, thinking that this would cause the command
to be run after hitting 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 it doesn't do anything. What must I do for self.search
to be run when Enter is pressed?
Your code looks fine, but note that the focus must be on the button if you want Return
to call self.search()
. You can change the focus from widget to widget by pressing Tab
. The widget in focus is outlined with a thin black line. You may have to press Tab
one or more times to move the focus to the button before pressing Return
.
If you want Return
to work anywhere in the GUI window, then 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 could use
button.bind('<Return>', self.search)
button.focus()
Doing it this way, pressing Return
calls self.search()
only when the button has the focus, but the button gets the focus when the app begins.
Regarding the use of *args
and **kwargs
:
**kwargs
allows arbitrary keyword arguments to be passed to __init__
.
When **kwargs
is used in a function definition like this:
def __init__(self, master, **kwargs):
and we instantiate SimpleApp
like this:
app = SimpleApp(root, title = 'Hello, world')
then Python sets kwargs
to a dict containing the keyword arguments, e.g. {'title':'Hello, world'}
. Note that **kwargs
is Python syntax which can only be used in function definitions and function calls (see below), but kwargs
itself is just a dict.
kwargs
is then passed to Frame
:
frame = tk.Frame(master, **kwargs)
Now, when **kwargs is used in a function call, the key-value pairs in the kwargs
dict get expanded so that the above function call is equivalent to
frame = tk.Frame(master, title = 'Hello, world')
Since Frame
can take numerous keyword arguments, and I don't know them all and don't wish to enumerate them, it is advantageous to use **kwargs
.
Note also that even if new keyword arguments were added to Frame
at some later date, my code will still work, whereas if I spelled out the keywords explicitly then my code would not automatically "upgrade" if Frame
's allowable keywords were to change.
*args
, similarly, allows you to include arbitrary positional arguments to search
:
def search(self,*args):
Python sets args
to a list containing all the 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 say
button = tk.Button(frame, text = 'search', command = self.search)
self.search()
is called with no argumens 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 which has attributes (time, state, type, widget, x, y, etc) which allow you to learn more about what event took place.
Another, perhaps better, way to define search
would have been
def search(self, event = None):
...
This would have made it clear that search
may be passed 0 or 1 arguments, and not simply and arbitary number of arguments. It also would have provided easier access to event
if an event were passed to search
.
Reference:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With