Search code examples
pythontkinteroptionmenu

Tkinter have one option menu affect the next


I want to make a little program that will take the list of folders in a directory and list them in a selection menu for this I have used optionmenu but I have seen people using combomenu as well so will happily change if it is a better option. Once the selection has been made in the project menu I want the second menu to update with folders inside of the selected project menu. It would be the same for the last step but that I guess will be a very similar process. Also is there a good way of printing the selection of the optionmenu as well?

Thanks!

import os, sys
from tkinter import *
from tkinter import ttk



def findshots(*args):
    print("change")
    return 1




# -------- project selection ---------

currentprojects = './dummy/projects'
currentprojectslist = os.listdir(currentprojects)

# --------- shots list -------------------

projectselection = findshots()
currentshots = "./dummy/projects/{}/shots".format(currentprojectslist[projectselection])
currentshotslist = os.listdir(currentshots)




# ----------  script list -------------------

shotselection = 0
currentnk = "./dummy/projects/{}/shots/{}/nk".format(currentprojectslist[projectselection], currentshotslist[
    shotselection])
currentnklist = os.listdir(currentnk)


# ----------------------------------------------

# --------MAIN--------------



root = Tk()

root.geometry("1000x1000+800+100")
root.resizable(width=False, height=False)





# ------- project -----------
projectmenuvar = StringVar(root)
projectmenuvar.set(currentprojectslist[0])
projectmenuvar.trace("w", findshots)


projectmenuvar = OptionMenu(root, projectmenuvar, *currentprojectslist)
projectmenuvar.pack()





# ----------- shot -------------



shotsmenuvar = StringVar(root)
shotsmenuvar.set(currentshotslist[0])



shotsmenuvar = OptionMenu(root, shotsmenuvar, *currentshotslist)
shotsmenuvar.pack()


root.mainloop()

Solution

  • As OptionMenu is like popup-menu, you can update shotsmenu menu item list whenever projectmenu is changed. Below is modified code based on yours:

    from tkinter import *
    import os
    
    root = Tk()
    
    # get project list
    currentprojects = './dummy/projects'
    currentprojectslist = os.listdir(currentprojects)
    
    def findshots(*args):
        project = projectmenuvar.get()
        print('project changed:', project)
        # get shot list
        currentshots = '{}/{}/shots'.format(currentprojects, project)
        currentshotslist = os.listdir(currentshots)
        print(currentshotslist)
        # update the shotsmenu
        menu = shotsmenu['menu']
        menu.delete(0, 'end') # remove existing list
        for shot in currentshotslist:
            menu.add_command(label=shot, command=lambda val=shot: shotsmenuvar.set(val))
        # select the first shot
        shotsmenuvar.set(currentshotslist[0])
    
    def on_shot_changed(*args):
        print('shot changed:', shotsmenuvar.get())
    
    projectmenuvar = StringVar()
    projectmenuvar.trace('w', findshots)
    projectmenu = OptionMenu(root, projectmenuvar, *currentprojectslist)
    projectmenu.config(width=15)
    projectmenu.pack()
    
    shotsmenuvar = StringVar()
    shotsmenuvar.trace('w', on_shot_changed)
    shotsmenu = OptionMenu(root, shotsmenuvar, ())
    shotsmenu.config(width=15)
    shotsmenu.pack()
    
    # select the first project
    projectmenuvar.set(currentprojectslist[0])
    
    root.mainloop()