saulspatz
saulspatz

Reputation: 5271

how to invoke button command with enter key

In tkinter, when a button has the focus, you can press the space bar to execute the command associated with that button. I'm trying to make pressing the Enter key do the same thing. I'm certain I've done this in the past, but I can't find the code, and what I'm doing now isn't working. I'm using python 3.6.1 on a Mac.

Here is what I've tried

self.startButton.bind('<Return>', self.startButton.invoke)

Pressing the Enter key has no effect, but pressing the space bar activates the command bound to self.startButton. I've tried binding to <KeyPress-KP_Enter> with the same result.

I also tried just binding to the command I want to execute:

self.startButton.bind('<Return>', self.start)

but the result was the same.

EDIT

Here is a little script that exhibits the behavior I'm talking about.

import tkinter as tk

root = tk.Tk() 
def start():
    print('started')
    startButton.configure(state=tk.DISABLED)
    clearButton.configure(state=tk.NORMAL)

def clear():
    print('cleared')
    clearButton.configure(state=tk.DISABLED)
    startButton.configure(state=tk.NORMAL)    

frame = tk.Frame(root)
startButton = tk.Button(frame, text = 'Start', command = start, state=tk.NORMAL)
clearButton = tk.Button(frame, text = 'Clear', command = clear, state = tk.DISABLED)
startButton.bind('<Return>', start) 
startButton.pack()
clearButton.pack()
startButton.focus_set()  
frame.pack() 
root.mainloop()

In this case, it works when I press space bar and fails when I press Enter. I get an error message when I press Enter, saying that there an argument was passed, but none is required. When I change the definition of to take dummy argument, pressing Enter works, but pressing space bar fails, because of a missing argument.

I'm having trouble understanding how wizzwizz4's answer gets both to work. Also, I wasn't seeing the error message when I pressed Enter in my actual script, but that's way too long to post.

** EDIT AGAIN **

I was just overlooking the default value of None in Mike-SMT's script. That makes things plain.

Upvotes: 3

Views: 1383

Answers (2)

Mike - SMT
Mike - SMT

Reputation: 15236

Your use of self.startButton.bind('<Return>', self.start) should work fine as long as compensate for the event that the bind will send to the function/method.

Here is a simple example that will work with the enter key as long as the button has focus.

import tkinter as tk


root = tk.Tk()

def do_something(event=None):
    print("did something!")

btn = tk.Button(root, text="Do something", command=do_something)
btn.pack()
btn.bind("<Return>", do_something)
#root.bind("<Return>", do_something) will work without the button having focus.

root.mainloop()

Upvotes: 3

wizzwizz4
wizzwizz4

Reputation: 6426

This only works when the button has keyboard focus. Also, an argument representing the event object is passed to the callable provided. The former doesn't seem to be the problem, so try:

self.startButton.bind('<Return>', lambda e: self.startButton.invoke())

Upvotes: 3

Related Questions