简体   繁体   中英

Obtain values from tkinter OptionMenu

1 I chosed values from OptionMenu

2 clicked button

But callback function parse printed default values of OptionMenu. What I did wrong?

My code

from tkinter import *
from functools import partial


def parse(shop, city):
    print(f"Parse {city} {shop}") # prints "all shops" but i expected "magnit" because i chosed it


master = Tk()

variable_shop = StringVar(master)
variable_shop.set("all shops") # default value

w = OptionMenu(master, variable_shop, "all shops", "5ka", "magnit", "three").pack()

variable_city = StringVar(master)
variable_city.set("all cities") # default value
w2 = OptionMenu(master, variable_city, "all cities", "Moscow", "Saint Petersburg").pack()

callback = partial(parse, variable_shop.get(), variable_city.get())
b1 = Button(text="Run with values from OptionMenu", command=callback).pack()

mainloop()

Your callback line runs when the program boots, so it saves the values at boot. You need to move those get() calls someplace that gets run later, when the user clicks the button. Putting them in the parse function makes sense, and also removes the need for partial.

from tkinter import *

def parse():
    city = variable_city.get()
    shop = variable_shop.get()
    print(f"Parse {city} {shop}") 

master = Tk()

variable_shop = StringVar(master)
variable_shop.set("all shops") # default value

OptionMenu(master, variable_shop, "all shops", "5ka", "magnit", "three").pack()

variable_city = StringVar(master)
variable_city.set("all cities") # default value
OptionMenu(master, variable_city, "all cities", "Moscow", "Saint Petersburg").pack()

Button(text="Run with values from OptionMenu", command=parse).pack()

mainloop()

Consider this line of code:

callback = partial(parse, variable_shop.get(), variable_city.get())

It is functionally identical to this:

shop = variable_shop.get()
city = variable_city.get()
callback = partial(parse, shop, city)

In other words, you're calling the get methods about a millisecond after creating it, rather than waiting until the user has clicked the button.

You don't need to use partial at all. Just have the callback call a regular function, and have the function retrieve the values. This will make the code easier to write, easier to understand, and easier to debug.

def parse():
    shop = variable_shop.get()
    city = variable_city.get()
    print(f"Parse {city} {shop}") 
...
b1 = Button(text="Run with values from OptionMenu", command=parse)
b1.pack()

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