0

In tkinter using the OptionMenu widget when I click on it, I would like to change the amount of available options in such a way that when I type "a" on the keyboard, the OptionMenu would only show the options that start with that a. The problem is I cant bind the keyboard event to the OptionMenu. I only hear a beep sound. Is it possible to do it?

import tkinter as tk

root = tk.Tk()

options = ["orange", "banana", "apple"]
var = tk.StringVar(value=options[0])
menu = tk.OptionMenu(root, var, *options)
menu.pack()

def on_key(event):
    print(event)

menu.bind("<Key>", on_key)

root.mainloop()

2 Answers2

0

funny enough, I just asked the same question yesterday night after trying a ton of things (nobody was able to answer mine so far). Apparently, both OptionMenus and MenuButtons only admit the keyboard input (and predefinted functions) of arrow keys, return and escape, when posted (when the cascade is displayed).

But today I came up with a solution (for my particular case) that might also interest you, and that's changing the options before displaying the cascade.

Here's my question and my own answer from today: is there a way to change the keys to navigate the tkinter MenuButton options in python?

In your case, I would bind to the "a" key the hiding of all the options inside the OptionMenu that you want BEFORE displaying the menu (the menu would have to be at least focused to do so, or referenced in any way).

You can use my code to identify the index of the options that start with "a" (if they are contained in a list or a dictionary), and use these functions to hide or unhide the radiobuttons (or other widgets) with that label:


def hide_radiobuttons():
    for rb in radiobuttons:
        rb.config(state="disabled")

def show_radiobuttons():
    for rb in radiobuttons:
        rb.config(state="normal")

This might not be suitable for your particular case, but it's an option.

Also, I'm not an experienced coder, so there might be mistakes in my solution (even thought it worked for me).

Hope this helps.

Cheers.

peputito
  • 13
  • 3
  • I suggested you to use combobox. – toyota Supra Mar 11 '23 at 01:40
  • As far as I know (I just checked), the problem remains the same in that scenario, comboboxes also seem to only allow the input of arrow keys, return and escape, when the cascade is displayed. – peputito Mar 11 '23 at 07:58
  • In the end I couldn't find a direct solution. I just used this [Tkinter - How to create a combo box with autocompletion](https://stackoverflow.com/questions/12298159/tkinter-how-to-create-a-combo-box-with-autocompletion) – Mike Kol Mar 15 '23 at 15:29
0

A bit too late, but if you want to save yourself some lines, I finally found a direct solution to both our problems. We just had to name the menu inside the OptionMenu/MenuButton and bind whatever we wanted there:


import tkinter as tk

root = tk.Tk()

options = ["orange", "banana", "apple"]
var = tk.StringVar(value=options[0])
menu = tk.OptionMenu(root, var, *options)

cascade = menu["menu"]

menu.pack()

def on_key(event=None):
    print('Its ALIVEEEE')

cascade.bind("<p>", on_key)

root.mainloop()

I have just moved to Linux and this works here, I can only assume it does too in any other OS.

peputito
  • 13
  • 3
  • That's not the problem. An op wanted to type 'o' or 'b' or 'a' – toyota Supra Mar 20 '23 at 12:36
  • Op literally says: "The problem is I cant bind the keyboard event to the OptionMenu". And that's what the code example shows, that specific problem. And that's what I've proposed a solution for. Once you are able to make any key work when the cascade of the OptionMenu is posted, the rest of the task can be solved by hiding/unhiding options with the other solution I proposed. – peputito Mar 20 '23 at 13:50
  • OIC I will try on linux later. – toyota Supra Mar 20 '23 at 14:01
  • Let me know if you have any problem and we'll try to solve it. – peputito Mar 20 '23 at 14:53