pythontkinterttkoptionmenutkinter-menu

Update on the fly a ttk.OptionMenu without affecting its previous callback/command


I am doing a large GUI with different ttk.OptionMenu widgets that need to be updated often depending on the interaction with the user. Each time the user selects another value from the menu, there is a function callback by the widget via the command input. The command works fine until I need to update the possible values within the OptionMenu widget. After updating using add_command, my previous callback does not work anymore.

Is there any way of updating the possible inputs of a ttk.OptionMenu without affecting its original callback? Let me put a dummy example to illustrate my problem. My original code would be like

from tkinter import *
from tkinter import filedialog, messagebox, ttk

        
def printing(variable,*args):
    
    print('ok')
      
    if variable: 
        print(variable)

root=Tk()
List=['Madrid', 'Paris', 'Brussels']
variable = StringVar()

optionmenu = ttk.OptionMenu(root,variable,'', *List,
                            command=printing) 
optionmenu.pack()      
root.mainloop() 

Then the user would update the list dynamically, and the menu needs to be updated on the fly, using:

newList = ['Madrid', 'Paris', 'Brussels', 'London']
menu = optionmenu["menu"]
menu.delete(0, "end")
for string in newlist:
    menu.add_command(label=string,
                      command=lambda value=string: variable.set(value))

but doing this operation, the callback printing would not work anymore. Also important to mention that one clicked in one option it should become the value showed by the OptionMenu ( so the StringVar variable is settled to that input)

I hope it is clear


Solution

  • There is an internal class _setit in tkinter module which is used by OptionMenu internally to populate the values. You can use this class as below:

    from tkinter import filedialog, messagebox, ttk, _setit
    ...
    
    for value in newList:
        menu.add_command(label=value, command=_setit(variable, value, printing))