Search code examples
pythondynamictkinteroptionmenu

Python - tkinter How to read the second drop down values


I am trying to read the values of the selected dropdown list from the second dropdown option in below code. [Example: 'Germany', 'France', 'Switzerland']

Here i can able to read the first drop down values by using function called fun()

But same am unable to read the second drop down values.

Suggest me how to read the second drop down values from the below code

Here is the code.

import sys
if sys.version_info[0] >= 3:
    import tkinter as tk
else:
    import Tkinter as tk


class App(tk.Frame):

    def __init__(self, master):
        tk.Frame.__init__(self, master)

        self.dict = {'Asia': ['Japan', 'China', 'Malaysia'],
                     'Europe': ['Germany', 'France', 'Switzerland']}

        self.variable_a = tk.StringVar(self)
        self.variable_b = tk.StringVar(self)

        self.variable_a.trace('w', self.update_options)

        self.optionmenu_a = tk.OptionMenu(self, self.variable_a, *self.dict.keys(), command=self.fun)
        self.optionmenu_b = tk.OptionMenu(self, self.variable_b, '')

        self.variable_a.set('Asia')

        self.optionmenu_a.pack()
        self.optionmenu_b.pack()
        self.pack()

    def fun(self,value):
        print(value)


    def update_options(self, *args):
        countries = self.dict[self.variable_a.get()]
        self.variable_b.set(countries[0])

        menu = self.optionmenu_b['menu']
        menu.delete(0, 'end')

        for country in countries:
            menu.add_command(label=country, command=lambda nation=country: self.variable_b.set(nation))


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    app.mainloop()

Solution

  • A tkinter variable has a trace method that can be used to fire a callback function when the variable is set. In your case, add this to __init__:

    self.variable_b.trace('w', self.fun2)
    

    And make a new method to handle it:

    def fun2(self, *args):
        print(self.variable_b.get())