I was wondering if there is any way for me to see what the User has selected among the list displaying, let\'s say: [\"Apple\",\"Orange\",\"Grapes\"]
right after th
Trace the StringVar
.
from Tkinter import *
def option_changed(*args):
print "the user chose the value {}".format(variable.get())
print a
master = Tk()
a = "Foo"
variable = StringVar(master)
variable.set("Apple") # default value
variable.trace("w", option_changed)
w = OptionMenu(master, variable, "Apple", "Orange", "Grapes")
w.pack()
mainloop()
Here, option_changed
will be called whenever the user chooses an option from the option menu.
You can wrap the trace argument in a lambda to specify your own parameters.
def option_changed(foo, bar, baz):
#do stuff
#...
variable.trace("w", lambda *args: option_changed(qux, 23, "hello"))
When I come across widgets with annoying interfaces - such as OptionMenu
, I generally will write a class around it to abstract away the annoying attributes. In this case, I really dislike the verbosity of using the StringVar every time I want to create a dropdown, so I simply created a DropDown
class which includes the StringVar
within the class (written in Python 3.5, but translates easily to all):
class DropDown(tk.OptionMenu):
"""
Classic drop down entry
Example use:
# create the dropdown and grid
dd = DropDown(root, ['one', 'two', 'three'])
dd.grid()
# define a callback function that retrieves the currently selected option
def callback():
print(dd.get())
# add the callback function to the dropdown
dd.add_callback(callback)
"""
def __init__(self, parent, options: list, initial_value: str=None):
"""
Constructor for drop down entry
:param parent: the tk parent frame
:param options: a list containing the drop down options
:param initial_value: the initial value of the dropdown
"""
self.var = tk.StringVar(parent)
self.var.set(initial_value if initial_value else options[0])
self.option_menu = tk.OptionMenu.__init__(self, parent, self.var, *options)
self.callback = None
def add_callback(self, callback: callable):
"""
Add a callback on change
:param callback: callable function
:return:
"""
def internal_callback(*args):
callback()
self.var.trace("w", internal_callback)
def get(self):
"""
Retrieve the value of the dropdown
:return:
"""
return self.var.get()
def set(self, value: str):
"""
Set the value of the dropdown
:param value: a string representing the
:return:
"""
self.var.set(value)
Example usage:
# create the dropdown and grid, this is the ONLY required code
dd = DropDown(root, ['one', 'two', 'three'])
dd.grid()
# optionally, define a callback function that retrieves the currently selected option then add that callback to the dropdown
def callback():
print(dd.get())
dd.add_callback(callback)
Edited to add: Not long after creating this post, I got annoyed with a few other attributes of tk and ended up creating a package called tk_tools to make dropdowns and checkbuttons easier along with addressing other annoyances.