Search code examples
pythontkinteroptionmenu

Relative OptionMenu list in Tkinter Python


I working on GUI for insering data to a database.I need to create a dropdown list(combobox) that will change it's values based on a value chosen in another dropdown list.

I've tried to use if statment of chosen values from first OptionMenu to based of StringVar but its not working. Do you have any suggestions?

    Type =('Option1', 'Option2', 'Option3')
    CategoryA = ('1','2', '3')
    CategoryB= ('A','Transport')

    TypeSelected = StringVar()
    TypeSelected.set(Type[0])
    TypeOption = OptionMenu(self,TypeSelected,*Type)
    TypeOption.grid(row=1, column=1)

    CategoryLabel = Label(self,text='Category')
    CategoryLabel.grid(row=2, column=0)

    CategorySelected = StringVar()
    print(str(TypeSelected))
    if(str(TypeSelected)=='Przychody'):
        CategorySelected.set(CategoryPrzychody[0])
        category = CategoryPrzychody
    else:
        CategorySelected.set(CategoryRozchody[0])
        category = CategoryRozchody
    CategoryOption = OptionMenu(self,CategorySelected,*category)
    CategoryOption.grid(row=2,column=1)

Solution

  • You're on the right lines, but this code won't change the options after mainloop() has been called as it only runs once at the start of the program. You need to trace the StringVar in the first OptionMenu, and whenever it's changed call a function to change the options in the second OptionMenu. To change the options you need to delete the existing ones, and then add new ones using add_command(). For example:

    import tkinter as tk
    
    
    def set_options(*args):
        """
        Function to configure options for second drop down
        """
        global option, option2, menu2
        a = ['1', '2', '3']
        b = ['4', '5', '6']
    
        # check something has been selected
        if option.get() == '(select)':
            return None
    
        # refresh option menu
        option2.set('(select)')
        menu2['menu'].delete(0, 'end')
    
        # pick new set of options
        if option.get() == 'A':
            new_options = a
        else:
            new_options = b
    
        # add new options in
        for item in new_options:
            menu2['menu'].add_command(label=item, command=tk._setit(option2, item))
    
    
    root = tk.Tk()
    
    # drop down to determine second drop down
    option = tk.StringVar(root)
    option.set('(select)')
    
    menu1 = tk.OptionMenu(root, option, 'A', 'B')
    menu1.pack()
    
    # trace variable and change second drop down
    option.trace('w', set_options)
    
    # second drop down
    option2 = tk.StringVar(root)
    option2.set('(select)')
    
    menu2 = tk.OptionMenu(root, option2, '(select)')
    menu2.pack()
    # initialise
    set_options()
    
    root.mainloop()