Ryan Barrett
Ryan Barrett

Reputation: 25

How to add key binding?

None of the other stackoverflow suggestions, nor any other outside documentation has shown me how to successfully bind a key to a function. Below are links I've tried (code copied and pasted) and had no luck with. I see many people suggesting focus as a reason for failure, as though the frame containing the button isn't the user's target and therefore isn't active; nothing has come from this however. Below are links I have tried:

http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

https://softwareengineering.stackexchange.com/questions/213935/why-use-classes-when-programming-a-tkinter-gui-in-python

python tkinter how to bind key to a button

http://www.java2s.com/Code/Python/GUI-Tk/SetButtontogetfocus.htm

How to bind a keypress to a button in Tkinter

I am running Python 3.6 in PyCharm 5.0.4.

The code in the links above are what I've been using/modifying to see how it works but not a single attempt has ended with an action being carried out. The furthest I've gotten is an error message.

Thanks.

EDIT: code I am using below (from most recent link)

from tkinter import *
root = Tk()

def LeftTurn(event):
    print('left')
frame=Frame(root, width=100, height=100)
frame.bind("<Left>", LeftTurn)   #Binds the "left" key to the frame and exexutes yourFunction if "left" key was pressed
frame.pack()


root.geometry("640x480")
root.title("Rover ")


root.mainloop()

I also tried this one (below)

from tkinter import *

root = Tk()

def yourFunction(event):
    print('left')

frame = Frame(root, width=100, height=100)

frame.bind("<Left>",yourFunction)   #Binds the "left" key to the frame and exexutes yourFunction if "left" key was pressed
frame.pack()

root.mainloop()

Upvotes: 1

Views: 1646

Answers (2)

Mike - SMT
Mike - SMT

Reputation: 15236

So your frame needs to get focus somehow in order for your binding to work.

Take this example code below. If you click the test button the focus will be set to the frame and you can press the left arrow key and your function will print to console. If you then click inside the entry field the focus will be moved to the entry field and your bind will no longer work until the frame gets focus again.

So this can be useful for some stuff but I have never really needed to bind to a "frame" but rather the root or toplevel windows or a specific widget that can interact with they keyboard or mouse directly like Entry or Text.

from tkinter import *


root = Tk()

def LeftTurn(event):
    print('left')

frame=Frame(root)
Button(frame, text="test", command= frame.focus).pack()
Entry(frame).pack()

frame.bind('<Left>', LeftTurn)
frame.pack()

root.mainloop()

You probably want to bind to root instead for this code. This will always trigger no mater what widget in your root window is clicked on or in what frame.

from tkinter import *


root = Tk()

def LeftTurn(event):
    print('left')

frame=Frame(root)
Button(frame, text="Button").pack()

root.bind('<Left>', LeftTurn)
frame.pack()

root.mainloop()

Upvotes: 1

Novel
Novel

Reputation: 13729

You are right, that's a focus issue. It's impossible for the user to focus on a Frame, so you either have to do it for them by adding

frame.focus()

Or you can bind to something that is not going out of focus, like the root window:

root.bind("<Left>", LeftTurn) 

Upvotes: 1

Related Questions