0

Is there any way to add options in an OptionMenu object without using the command flag?

I have seen many posts, such as this one, showing how the add_command will update/remove/add options to an already existing OptionMenu object. For example, this snippet of code removes all options in serialPortOptionMenu and repopulates the option menu with different options:

serialPortOptionMenu["menu"].delete(0, "end")
for serialPort in serialPortsArray:
    serialPortOptionMenu["menu"].add_command(label=serialPort[1], command=lambda v=serialPort: serialPortFunc(v))

However, something like this seems to overwrite the original command flag I wrote when creating the OptionMenu object:

serialPortOptionMenuValue = Tkinter.StringVar(optionMenuFrame)
serialPortOptionMenuValue.set(serialPorts[0])
serialPortOptionMenu = Tkinter.OptionMenu(optionMenuFrame, serialPortOptionMenuValue, *serialPorts, command=lambda *args: callbackFuncWhenOptionMenuSelectsAnotherOption(*args))
serialPortOptionMenu.grid(row=3, column=0, columnspan=2, sticky="we")

As I'm sure many people are wondering why I am setting a command within an OptionMenu (weird I know), it is because I want a callback function to be called when the user picks a new option.

"What about the trace option"-Everyone...Yes, I am aware of this as well, but because I am reading/writing new values to the Tkinter variable in code without having the OptionMenu solely change it, using trace within Tkinter would not be an effective substitute for just tracking when the user selects a new option in the OptionMenu.

Why am I changing the Tkinter value in code and not having the OptionMenu do it? Because I thought it would be nice to modify the Tkinter value string with something like a ~ at the end of the string to signify something is happening behind the scenes that isnt completed yet, and only when it is completed will the ~ go away, hence the reading and writing to the value without having the OptionMenu solely change it.

What I am primarily interested in is if anyone knows of other ways to add options to an OptionMenu object without using

myMenu["menu"].add_command(..., command=...)

As it seems to be removing my original callback function.

Note: Having two OptionMenus and performing grid_remove/grid on them to hide/reveal them also crossed my mind, but just seems to messy.

Community
  • 1
  • 1
AustinTronics
  • 11
  • 1
  • 6

2 Answers2

1

There is no other way. An option menu is nothing more than a menubutton and a menu with a custom binding. You can create your own OptionMenu and add any methods you want.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I rarely ever use ttk directly, except for making tabs using ttk.Notebook. Briefly looked up making a Menubutton from [here](http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-Menubutton.html). Seems similar to Tkinter.OptionMenu in how its instantiated (parent, options, etc). Think you can put up a brief example or point me towards a good resource to accomplish what I'm trying to do? – AustinTronics Oct 23 '16 at 05:20
0

I don't know if it will be useful to you anymore, but maybe somebody else will be looking for this as I was. You actually just need to put the command as a callback parameter in the command you use to add the item (I found tk._setit):

def refresh_dropdown():
    # Reset var and delete all old options
    var.set('')
    dropdown['menu'].delete(0, 'end')

    # Insert list of new options (tk._setit hooks them up to var)
    new_choices = ['a', 'b', 'c', '...'] # you can make a dictionary[key_from_previous_dropdown.get()] as I did in my case
    for choice in new_choices:
        dropdown['menu'].add_command(label=choice, command=_setit(var, choice, new_command))


dropdown = OptionMenu(app, var, command=new_command)