The Tkinter OptionMenu
widget provides a dropdown list from which the user can select a single item. It’s a convenient way to offer a predefined set of choices without taking up too much space in your graphical user interface (GUI). See how to create and use the OptionMenu
widget.
Basic OptionMenu Creation
To create an OptionMenu
, you need:
- A
StringVar
to hold the currently selected value. - A list of options to display in the dropdown.
import tkinter as tk
def show_selection():
selected_option = selected_value.get()
print(f"Selected: {selected_option}")
result_label.config(text=f"You chose: {selected_option}")
root = tk.Tk()
root.title("OptionMenu Example")
options = ["Option A", "Option B", "Option C", "Option D"]
selected_value = tk.StringVar(root)
selected_value.set(options[0]) # Set the initial default value
option_menu = tk.OptionMenu(root, selected_value, *options)
option_menu.pack(pady=20)
select_button = tk.Button(root, text="Show Selection", command=show_selection)
select_button.pack(pady=10)
result_label = tk.Label(root, text="No selection yet")
result_label.pack(pady=5)
root.mainloop()
In this example:
options
is a list of strings that will appear in the dropdown.selected_value = tk.StringVar(root)
creates a string variable to store the chosen option.selected_value.set(options[0])
sets the initial value displayed in the OptionMenu.option_menu = tk.OptionMenu(root, selected_value, *options)
creates the OptionMenu.- The first argument is the parent widget (root).
- The second argument is the StringVar that will hold the selected value.
- The *options unpacks the list of options, passing each item as a separate argument to the OptionMenu constructor.
- The show_selection() function retrieves the current value using
selected_value.get()
.
Executing a Command on Selection Change
You can also configure the OptionMenu to call a function automatically whenever the selection changes, without needing a separate button.
import tkinter as tk
def on_option_change(*args): # *args is required for StringVar trace
current_selection = selected_value.get()
print(f"Option changed to: {current_selection}")
result_label.config(text=f"Current selection: {current_selection}")
root = tk.Tk()
root.title("OptionMenu with Command")
options = ["Apple", "Banana", "Cherry", "Date"]
selected_value = tk.StringVar(root)
selected_value.set(options[0])
# Trace the StringVar to call a function on change
selected_value.trace("w", on_option_change) # "w" means write (when value changes)
option_menu = tk.OptionMenu(root, selected_value, *options)
option_menu.pack(pady=20)
result_label = tk.Label(root, text=f"Current selection: {selected_value.get()}")
result_label.pack(pady=5)
root.mainloop()
Here:
selected_value.trace("w", on_option_change)
registers a callback function (on_option_change) to be executed whenever the StringVar’s value is written to (“w”).- The on_option_change function must accept *args because the trace mechanism passes extra arguments (name, index, mode) to the callback.
Adding/Removing Options Dynamically
You can dynamically add or remove options from an OptionMenu by modifying its underlying menu.
import tkinter as tk
def add_option():
new_option = f"New Option {len(options) + 1}"
options.append(new_option)
update_option_menu()
def remove_option():
if len(options) > 1:
options.pop()
if selected_value.get() not in options and options: # If removed selected, set to first
selected_value.set(options[0])
elif not options: # If no options left
selected_value.set("") # Or disable the menu
update_option_menu()
def update_option_menu():
option_menu['menu'].delete(0, 'end') # Clear existing options
for option in options:
option_menu['menu'].add_command(label=option, command=tk._set_option_menu(selected_value, option))
root = tk.Tk()
root.title("Dynamic OptionMenu")
options = ["Item 1", "Item 2"]
selected_value = tk.StringVar(root)
selected_value.set(options[0])
option_menu = tk.OptionMenu(root, selected_value, *options)
option_menu.pack(pady=10)
add_button = tk.Button(root, text="Add Option", command=add_option)
add_button.pack(pady=5)
remove_button = tk.Button(root, text="Remove Option", command=remove_option)
remove_button.pack(pady=5)
root.mainloop()
This advanced example demonstrates how to clear and re-populate the OptionMenu’s internal menu when the list of options changes.
Key Points
- Always use a
tk.StringVar
to manage the selected value. - Pass the
StringVar
and then unpack your list of options (*options) to the OptionMenu constructor. - Use
StringVar.trace("w", callback_function)
to execute code when the selection changes. - Dynamically modifying options requires direct manipulation of the OptionMenu’s internal menu.
The OptionMenu widget is a simple yet effective way to present a list of choices to the user in a compact manner.