Keyboard shortcuts with tkinter in Python 3

Question:

I’ve created a menubar in Python 3, and I’m wondering how to add keyboard shortcuts and accelerators to it. Like hitting “F” for File Menu and whatnot.

Through some digging around I found the “underline=” attribute, but it doesn’t seem to work in Python 3. It didn’t work when I tried it, and the only documentation I found for it was for earlier versions of Python.

    menubar = Menu(master)

    filemenu = Menu(menubar, tearoff=0)
    .....
    menubar.add_cascade(label="File", underline=0, menu=filemenu)

Is there a way to do these things with tkinter in Python 3?

Asked By: Nathan R

||

Answers:

consider reading (http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm)

you have to bind your widget to an event to your function:

Keyboard events are sent to the widget that currently owns the
keyboard focus. You can use the focus_set method to move focus to a
widget:

Capturing keyboard events

from Tkinter import *

root = Tk()

def key(event):
    print "pressed", repr(event.char)

def callback(event):
    frame.focus_set()
    print "clicked at", event.x, event.y

frame = Frame(root, width=100, height=100)
frame.bind("<Key>", key)
frame.bind("<Button-1>", callback)
frame.pack()

root.mainloop()

If you run this script, you’ll find that you have to click in the
frame before it starts receiving any keyboard events.

I followed this guide to implement a ctrl+f binding to one of my functions a while ago:

toolmenu.add_command(label="Search Ctrl+f", command=self.cntrlf)
root.bind('<Control-f>', self.searchbox)
def cntrlf(self, event):
    self.searchbox()

for your file menu, you might want to consider implementing accelerators:

menubar.add_cascade(label="File", menu=fileMenu)
fileMenu.add_command(label="Exit", command=quit, accelerator="Ctrl+Q")
config(menu=menubar) 

for Menu options remember to use ALT followed by the first letter of the OptionName

file Menu = ALT followed by f
Tool Menu = ALT followed by t
and so on

hope this provides usefull

Answered By: glls

is there a way for the frame to receive events without clicking on the frame? If i scrolled over to the frame to click on it, i have already used time to get over there, might as well just click on the button as opposed to use the shortcut key.

The answer is to bind the whole root/master/window to a keybinding so that whenever you press that key a function is called which does your task.

import sys
from tkinter import *
from tkinter import filedialog

root = Tk()
menu_bar = Menu(root)
m1 = Menu(menu_bar, tearoff=0)
m1.add_command(label="Open...", underline=0, accelerator="Ctrl+O", command=filedialog.askopenfilename)
m1.add_command(label="Exit", underline=1, accelerator="Ctrl+Q", command=sys.exit)
menu_bar.add_cascade(label="File", underline=0, menu=m1)
menu_bar.add_cascade(label="Help", underline=0, menu=m1)
root.config(menu=menu_bar)

root.bind("<Control-o>", filedialog.askopenfilename)
root.bind("<Control-q>", sys.exit)
root.mainloop()

Press Alt to show the underlines. Alt+H, X opens the Help menu and activates the Exit item.

Answered By: Vedant Matanhelia