tkinter optionmenu first option vanishes tkinter optionmenu first option vanishes tkinter tkinter

tkinter optionmenu first option vanishes


The signature of the ttk.OptionMenu command is this:

def __init__(self, master, variable, default=None, *values, **kwargs):

This is the docstring:

"""Construct a themed OptionMenu widget with master as the parent, the resource textvariable set to variable, the initially selected value specified by the default parameter, the menu values given by *values and additional keywords.

Notice the default option which comes before the list of values. Instead of adding a blank item to the list of values, add whichever value you want as the default:

options = ['1', '2', '3']dropdown = ttk.OptionMenu(masterframe, value, options[1], *options)


I had this same question in another post. I had actually read this post and the answers, but did not pick up on the subtle differences between these two option menus. So, here's my stab at an answer as well, even though I am new to Python and tkinter.

As answered by @Bryan Oakley, yes, the doc string shows that there is an 'additional' required parameter when using ttk.OptionMenu rather than tk.OptionMenu. This difference will break (or at least mess up) your menu if you nilly-willy change the declaration from ttk.OptionMenu back to tk.OptionMenu. This is because tk.OptionMenu does not require the 'default' option to be declared. If you change ttk.OptionMenu back to tk.OptionMenu for some reason and leave the 'default' parameter in the declaration it will duplicate the first option in the OptionMenu. I was beating my head against the wall to figure out why these two did not behave exactly the same way. In my personal opinion this should not be the case. If anything, the 'default' parameter should be a keyword in both tk.OptionMenu and ttk.OptionMenu for compatibility. Maybe I'm wrong, but that's my opinion at this time.

To demonstrate this please see the below code:

# test-optionmenu.pyimport tkinter as tkfrom tkinter import ttkroot = tk.Tk()# tk OptionMenu listsoptionList1 = ('a', 'b', 'c')optionList2 = ('d', 'e', 'f')optionList3 = ('g', 'h', 'j')# ttk OptionMenu listsoptionList4 = ('1', '2', '3')optionList5 = ('4', '5', '6')optionList6 = ('7', '8', '9')optionList7 = ('z', 'x', 'y')# Set up the StringVars for each OptionMenuv1 = tk.StringVar()v2 = tk.StringVar()v3 = tk.StringVar()v4 = tk.StringVar()v5 = tk.StringVar()v6 = tk.StringVar()v7 = tk.StringVar()# tk.OptionMenu requires the default option# to be declared via the set() method.v2.set(optionList2[1]) # Default tk.OptionMenu value for om2v3.set(optionList3[2]) # Default tk.OptionMenu item value for om3v5.set(optionList5[1]) # Default ttk.OptionMenu item value for om5# -------------------------------------------# tk OptionMenu om1 does not automatically# assign a default based on your list, so# this does not display a list item initiallyom1 = tk.OptionMenu(root, v1, *optionList1)# -------------------------------------------# om2 demonstrates the 'default' parameter# from a former ttk.OptionMenu is ignored by# tk.OptionMenu because it needs to have the# default list item set via v2.set() call.# Notice the 'e' is displayed initially as# set, but now 'd' is duplicated in the list# as a remnant of the former ttk.OptionMenu# 'default' parameter.om2 = tk.OptionMenu(root, v2, optionList2[0], *optionList2)# -------------------------------------------# om3 is a tk.OptionMenu and has no 'default'# paramter declared like om2 above does.  Its# default is set to option 2, or 'j', and is# initially displayed on the dropdown.  None# of the OptionMenu list items are duplicated.om3 = tk.OptionMenu(root, v3, *optionList3)# -------------------------------------------# om4 shows how the 'default' parameter# from a former ttk.OptionMenu is ignored by# tk.OptionMenu because it needs to have the# default list item set via v4.set() call.# Since v4 is not set, nothing at all is# diplayed initially and when the OptionMenu# is clicked, it will show that '1' is listed# twice.om4 = tk.OptionMenu(root, v4, optionList4[0], *optionList4)# -------------------------------------------# by changing a tk.OptionMenu to a# ttk.OptionMenu, without properly declaring# the default OptionMenu item in the ttk way# will result in item '5' not being displayed# initially, and '4' will not be displayed in# the OptionMenu choices after a choice has# been made.om5 = ttk.OptionMenu(root, v5, *optionList5)# -------------------------------------------# om6 is the same as om5, except it does not# have a tk.OptionMenu default declared.  It# is only here for consiceness.om6 = ttk.OptionMenu(root, v6, *optionList6)# -------------------------------------------# om7 is the proper way to declare a# ttk.OptionMenu, with a default option# initially set.om7 = ttk.OptionMenu(root, v7, optionList7[2], *optionList7)# Pack'em all upom1.pack()om2.pack()om3.pack()om4.pack()om5.pack()om6.pack()om7.pack()# Execute the mainlooproot.mainloop()

I know the code may ugly to some, and if you really want to change it, go ahead. :)


just adding to the answers of the other guys, since they didn't work for me. I discovered that if you don't set the widget option in StringVar/IntVar, it doesn't show the standard value that's been set. It might seem silly but it took me a lot of time to figure this out. Hope it helps, see ya.Example:

master = tk.Tk()var = tk.StringVar(master)master.mainloop()