It works when you declared 'option2' in the Optionmenu() widget. More examples can be read from here and here.
from tkinter import *
main = Tk()
var = StringVar()
options = OptionMenu(main, var, 'option1', 'option2')
options.grid()
#options['menu'].add_command(label='option2')
main.mainloop()
I found that the menu option is used for creating items in a Menu() widget but not for a Optionmenu() widget. This is stated here. You can read more about how to declare a .Menu() widget here. All the best to your tkinter developments.
Edit1:
The reason why it was failing was because you did not declare the command option associated with the .add_command method. Having done this alone, you will notice that the Optionmenu still does not get updated with the new label of the added menu item. To resolve this issue, you have to use the .set() method of the Control Variable StringVar to do the updating. See revised script below.
from tkinter import *
def _print1(value):
# By default, callback to OptionMenu has a positional argument for the
# menu item's label.
print(value)
print(var.get())
def _print2():
var.set('option2')
print(var.get())
main = Tk()
var = StringVar()
options = OptionMenu(main, var, 'option1',command=_print1)
options.grid()
options['menu'].add_command(label='option2', command=_print2)
# To add more clickable menu items, the 'add_command' method requires you to
# to declare it's options 'label' and 'command'.
main.mainloop()
Edit2:
- Remark, I have added the
command aspect to options in Edit1. I
did not address earlier but thought it needed to be shown for
completeness.
- Responding to your question in your UPDATE, to do what you want, I
rewrote the script as a class object. Also I used the internal class
_setit found in tkinter, which the OptionMenu widget had used to
do configure the callback used by command. This approach overcame the issue you encountered.
Revised Code:
from tkinter import *
class App(Tk):
def __init__(self, parent=None):
Tk.__init__(self, parent)
self.parent=parent
self.createOM()
self.grid()
def createOM(self):
# Create OptionMenu
omlist=['option1']
self.var = StringVar()
self.options = OptionMenu(self, self.var, *omlist,
command=self._print1)
self.options.grid()
values = ['hello', 'bob', 'testing']
for v in values:
self.options['menu'].add_command(
label=v, command=_setit(self.var, v, self._print2))
# To add more clickable menu items, the 'add_command' method requires you to
# to declare it's options 'label' and 'command'.
def _print1(self, value, *args):
#callback for OptionMenu has these arguments because inherently it
#uses the _setit class to configure the callback with these arguments.
print()
print(value)
#self.var.set('option10') #Uncomment to change OptionMenu display
print(self.var.get())
def _print2(self, value, *args):
print()
print(value)
#self.var.set('option20') #Uncomment to change OptionMenu display
print(self.var.get())
#The following class is extracted from tkinter.
class _setit:
"""Internal class. It wraps the command in the widget OptionMenu."""
def __init__(self, var, value, callback=None):
self.__value = value
self.__var = var
self.__callback = callback
def __call__(self, *args):
self.__var.set(self.__value)
if self.__callback:
self.__callback(self.__value, *args)
if __name__ == "__main__":
app = App()
app.mainloop()