I am trying to create dropdown lists for a manufacturing workflow that are dependent on each previous choice - Product, Operation, Room number, Equipment, etc. I was able to make the 1st and 2nd selections, but after I choose the operation, I am not sure how to proceed to make a list of rooms that would be dependent on the operation selected. I tried to use the code previously provided on the ask link: Drop down list dependent from another drop down tkinter But as I try to create a 3rd drop-down, it shows empty. How do I proceed?
import tkinter as tk
products = ["A","B","C","D"]
operation = [["aX","aY"],
["bX","bY"],
["cX","cY"],
["dX","dY"]]
room =[ [["axP","axQ"], ["ayP","ayQ"]],
[["bxP","bxQ"], ["byP","byQ"]],
[["cxP","cxQ"], ["cyP","cyQ"]],
[["dxP","dxQ"], ["dyP","dyQ"]]]
root = tk.Tk()
canvas = tk.Canvas(root, height=1000, width= 1000, bg="white")
canvas.pack()
tkvar = tk.StringVar(root)
tkvar.set('Product')
tkvar2 = tk.StringVar(root)
tkvar2.set('Operation')
tkvar3 = tk.StringVar(root)
tkvar3.set('Room')
popupMenu1 = tk.OptionMenu(canvas, tkvar, *products)
popupMenu1.pack()
popupMenu2 = tk.OptionMenu(canvas, tkvar2, [])
popupMenu2.pack()
popupMenu3 = tk.OptionMenu(canvas, tkvar3, [])
popupMenu3.pack()
def change_dropdown(*args):
print("Chosen product " tkvar.get())
for i in range(len(products)):
if tkvar.get() == products[i]:
popupMenu2["menu"].delete(0, "end")
for item in operation[i]:
popupMenu2['menu'].add_command(label=item, command=tk._setit(tkvar2, item))
if tkvar2.get() == operation[i]:
popupMenu3["menu"].delete(0, "end")
for choice in operation[i]:
popupMenu3['menu'].add_command(label=choice, command=tk._setit(tkvar3, choice))
tkvar.trace('w', change_dropdown)
root.mainloop()
Greatly appreciate any help
CodePudding user response:
I am sure there is a nicer way to do this (Maybe with some dictionaries?), because like this you can easily confuse yourself with the indexing. However, the way you designed it right now it can be solved with a second function. Also for the operation
and room
you have a nested lists, so that is why you need the second for loop
.
import tkinter as tk
products = ["A","B","C","D"]
operation = [["aX","aY"],
["bX","bY"],
["cX","cY"],
["dX","dY"]]
room =[ [["axP","axQ"], ["ayP","ayQ"]],
[["bxP","bxQ"], ["byP","byQ"]],
[["cxP","cxQ"], ["cyP","cyQ"]],
[["dxP","dxQ"], ["dyP","dyQ"]]]
root = tk.Tk()
canvas = tk.Canvas(root, height=1000, width= 1000, bg="white")
canvas.pack()
tkvar = tk.StringVar(root)
tkvar.set('Product')
tkvar2 = tk.StringVar(root)
tkvar2.set('Operation')
tkvar3 = tk.StringVar(root)
tkvar3.set('Room')
popupMenu1 = tk.OptionMenu(canvas, tkvar, *products)
popupMenu1.pack()
popupMenu2 = tk.OptionMenu(canvas, tkvar2, [])
popupMenu2.pack()
popupMenu3 = tk.OptionMenu(canvas, tkvar3, [])
popupMenu3.pack()
def change_dropdown(*args):
print("Chosen product " tkvar.get())
for i in range(len(products)):
if tkvar.get() == products[i]:
popupMenu2["menu"].delete(0, "end")
for item in operation[i]:
popupMenu2['menu'].add_command(label=item, command=tk._setit(tkvar2, item))
def change_dropdown2(*args):
print("Chosen option " tkvar2.get())
for i in range(len(operation)):
for j in range(len(operation[i])):
if tkvar2.get() == operation[i][j]:
popupMenu3["menu"].delete(0, "end")
for choice in room[i][j]:
popupMenu3['menu'].add_command(label=choice, command=tk._setit(tkvar3, choice))
tkvar.trace('w', change_dropdown)
tkvar2.trace('w', change_dropdown2)
root.mainloop()
CodePudding user response:
You can use command
option of OptionMenu
instead of tracing tkinter variable:
import tkinter as tk
products = ["A","B","C","D"]
operation = [["aX","aY"],
["bX","bY"],
["cX","cY"],
["dX","dY"]]
room =[[["axP","axQ"], ["ayP","ayQ"]],
[["bxP","bxQ"], ["byP","byQ"]],
[["cxP","cxQ"], ["cyP","cyQ"]],
[["dxP","dxQ"], ["dyP","dyQ"]]]
root = tk.Tk()
canvas = tk.Canvas(root, height=1000, width= 1000, bg="white")
canvas.pack()
tkvar = tk.StringVar(root)
tkvar.set('Product')
tkvar2 = tk.StringVar(root)
tkvar2.set('Operation')
tkvar3 = tk.StringVar(root)
tkvar3.set('Room')
def on_product_change(product):
print("Chosen product", product)
i = products.index(product)
# update popupMenu2
menu = popupMenu2['menu']
menu.delete(0, 'end')
for op in operation[i]:
menu.add_command(label=op, command=tk._setit(tkvar2, op, on_operation_change))
tkvar2.set('Operation')
# clear popupMenu3
popupMenu3['menu'].delete(0, 'end')
tkvar3.set('Room')
def on_operation_change(op):
print("Chosen operation", op)
i = products.index(tkvar.get())
j = operation[i].index(op)
# update popupMenu3
menu = popupMenu3['menu']
menu.delete(0, 'end')
for item in room[i][j]:
menu.add_command(label=item, command=tk._setit(tkvar3, item, on_room_change))
tkvar3.set('Room')
def on_room_change(room):
print("Chosen room", room)
popupMenu1 = tk.OptionMenu(canvas, tkvar, *products, command=on_product_change)
popupMenu1.pack()
popupMenu2 = tk.OptionMenu(canvas, tkvar2, [])
popupMenu2.pack()
popupMenu3 = tk.OptionMenu(canvas, tkvar3, [])
popupMenu3.pack()
root.mainloop()