简体   繁体   中英

tkinter dynamic OptionMenu command not working

I'm using python 2.7.9 and my current issue is that for some reason, my OptionMenu 's command isn't working. Below is sample code of what I mean.

from Tkinter import *

root = Tk()
var = StringVar()
var.set("Choose a name...")
names = []

# Appends names to names list and updates OptionMenu
def createName(n):
    names.append(n)
    personName.delete(0, "end")
    menu = nameMenu['menu']
    menu.delete(0, "end")
    for name in names:
        menu.add_command(label=name, command=lambda name=name: var.set(name))

# what to run when a name is selected
def selection():
    print "Running"  # For testing purposes to see when/if selection runs
    print var.get()

# Option Menu for names
nameMenu = OptionMenu(root, var, (), command=lambda: selection())
nameMenu.grid(row=0, column=0, columnspan=2)
nameMenu.config(width=20)

# Entry for user to submit name
Label(root, text="Name").grid(row=1, column=0)
personName = Entry(root, width=17)
personName.grid(row=1, column=1)

# Add person Button
Button(root, text="Add Person", width=20, command=
       lambda: createName(personName.get())).grid(row=5, column=0, columnspan=2)

mainloop()

The purpose of this theoretical program is just to add a name to the OptionMenu , and then when you select the name, it will print it. I can add names to the OptionMenu just fine, but when it comes time for the OptionMenu to run the selection() function, it won't.

Now my best guess as to what's wrong is simply that the createName() function that the button is calling is also using the OptionMenu 's command up due to the line

menu.add_command(label=name, command=lambda name=name: var.set(name))

Is there anyway around this? Is it possible for an OptionMenu to have multiple commands?

You're on the right track... But instead of changing the StringVar you can pass the name into your selection() function like this:

from Tkinter import *

root = Tk()

var = StringVar()
var.set("Choose a name...")
names = []

# Appends names to names list and updates OptionMenu
def createName(n):
    names.append(n)
    personName.delete(0, "end")
    menu = nameMenu['menu']
    menu.delete(0, "end")
    for name in names:
        menu.add_command(label=name, command=lambda name=name: selection(name))

# what to run when a name is selected
def selection(name):
    var.set(name)
    print "Running"  # For testing purposes to see when/if selection runs
    print name

# Option Menu for names
nameMenu = OptionMenu(root, var, ())
nameMenu.grid(row=0, column=0, columnspan=2)
nameMenu.config(width=20)

# Entry for user to submit name
Label(root, text="Name").grid(row=1, column=0)
personName = Entry(root, width=17)
personName.grid(row=1, column=1)


# Add person Button
Button(root, text="Add Person", width= 20, command=lambda: createName(personName.get())).grid(row=5, column=0, columnspan=2)


mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM