I'm trying to add keyboard shortcuts in my application.
In the example below, when typing the combination option-1 the corresponding radiobutton is only selected if the menu is already open.
How to do what to do the same without opening the menu?
import tkinter as tk
class GrilleFenetre(tk.Tk):
""" interface graphique pour resoudre les hanjies """
def __init__(self):
super().__init__()
self.nitem=tk.IntVar()
self.menu_bar = tk.Menu(self)
self.config(menu=self.menu_bar)
self.menu_algo = tk.Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label="Algorithme", menu=self.menu_algo, underline=0)
self.menu_algo.add_radiobutton(label="Algorithme 1", variable=self.nitem, value=1, command=self.info, accelerator="Option-1")
self.menu_algo.add_radiobutton(label="Algorithme 2", variable=self.nitem, value=2, command=self.info, accelerator="Option-2")
self.menu_algo.add_radiobutton(label="Algorithme 3", variable=self.nitem, value=3, command=self.info, accelerator="Option-3")
self.menu_algo.add_separator()
self.menu_algo.add_radiobutton(label="Algorithme hanjie 1", variable=self.nitem, value=4, command=self.info, accelerator="Option-4")
self.menu_algo.add_radiobutton(label="Algorithme hanjie 2", variable=self.nitem, value=5, command=self.info, accelerator="Option-5")
self.bind_all("<Option-1>", lambda x: self.nitem.set(1))
self.bind_all("<Option-2>", lambda x: self.nitem.set(2))
self.bind_all("<Option-3>", lambda x: self.nitem.set(3))
self.bind_all("<Option-4>", lambda x: self.nitem.set(4))
self.bind_all("<Option-5>", lambda x: self.nitem.set(5))
def info(self):
n = self.nitem.get()
print("algo", n)
if __name__ == "__main__":
fenetre = GrilleFenetre()
fenetre.geometry("900x650+350+150") # Taille initiale de la fenĂȘtre
fenetre.mainloop()
I tried with the invoke method, I thought I used a shortcut that opens the menu and then selects the right entry, but I didn't find how to do it ?
When you press opt-1, tkinter doesn't see that as the key "1" with the "opt" modifier. Instead, the OS transforms it to a unique keysym. In this case the keysym is exclamdown
.
You can see the keysym for any key by temporarily adding the following to your program:
self.bind_all("<Any-Key>", lambda event: print(f"keysym: {event.keysym}"))
Thus, you need to bind to that keysym rather than <Opt-1>
, etc.
self.bind_all("<exclamdown>", lambda x: self.nitem.set(1))
For the numbers 1-5, the keysyms are exclamdown
, trademark
, sterling
, cent
, and infinity
, though that may be different on systems with different keyboard configurations.