Tkinter, although it caters well for basic needs, has very few active developers, and sometimes the best documentation is to look directly into the source code (in addition to the semi-official documentation that is on http://effbot.org/tkinterbook/)
Well, doing these two things I discovered that
- no support for scrollbars in menus (including Optionmenu)
- There is how to configure accelerators for each option, but I haven’t found a way for the accelerator to actually work directly.
You can try to explore the accelerators - from the Optionmenu it is possible to recover an internal menu using Mapping annotation. You can do: menu_interno = ent7["menu"]
and will have a menu object that will have all the methods here:
http://effbot.org/tkinterbook/menu.htm
At this point it is possible to configure an "Accelerator" for the inputs, for example: menu_interno.entryconfig(0, accelerator=energias[0][0])
, and the first letter of the first option in the "energies" list will be displayed to the right of the option in the menu (0 is the index of the input). But he just does it: the throttle didn’t work for me.
Solution
it is possible to use the bind
Tkinter normal to call a callback to a typed key when the menu is open, and make that callback set the variable and adjust the Optionbutton display "manually". As the function to do this will need the Optionmenu, the options and the initial variable, it is more practical to make the function itself create the Optionmenu and configure all this:
import tkinter
def accelerated_menu(root, variable, *options, command=None):
accelerators = {option[0]: option for option in options}
menu = tkinter.OptionMenu(root, variable, *options, command=command)
def callback(event):
key = getattr(event, "char", None)
if not key in accelerators:
return
value = accelerators[key]
variable.set(value)
menu["text"] = value
if command:
command(value)
for index, option in enumerate(options):
menu["menu"].entryconfig(index, accelerator=option[0])
menu["menu"].bind("<Key>", callback)
return menu
Just use the above function instead of calling the OptionMenu
directly, that the first letter of each option will be a shortcut. Of course, this is not ideal, since basically you limit yourself to always having a different letter in the first position- and in the case of repeated first letters, the top options are forgotten and the last ones are valid. But it is easy to create a logic with "if" to accept tuples of two items instead of strings in the options, allowing you to explicitly pass the shortcuts.
Alternative
The OptionMenu
just like some other widgets, it is built in pure Python from other more primitive widgets (in this case, the same "Menu" and a "Menubutton"). You can build a class by extending a Tkinter Widget that has not only the requirements you want, but is even nicer.
I would suggest a class that contains a grid of buttons, configured without relief and without border, that appears/disappears in a frame when clicking a button in permanent display. You would have complete control of the frame (so you can add scroll bar, show options in multiple columns), and buttons (you can configure keyboard shortcuts with "bind" of events).
Creating such a class will require a few hours of work and is not within the scope of this site - but is perfectly feasible.