I have a GUI that dynamically generates widgets based on the user selected number of systems:
These widgets are generated using a Callback function like the below sample of code:
class Window():
def __init__(self, master):
master.title('Production Analysis Tool')
# callback function to create entry boxes based on number of systems
self.L0 = Label(root, text="Equipment Parameters:", font = ('TKDefaultFont', 9, 'bold'))
self.L0.grid(row=3,column=0, sticky=W)
inverter_file = r'F:\CORP\PROJECTS\07599-A_Solar Development\Screening\_Production Analysis Tool\User Inputs\Inverter_Data.csv'
module_file = r'F:\CORP\PROJECTS\07599-A_Solar Development\Screening\_Production Analysis Tool\User Inputs\Module_Data.csv'
def update_scroll_region(event):
canvas.configure(scrollregion=canvas.bbox("all"))
def callback(*args):
dynamic_widgets = Frame(canvas)
canvas.create_window(0,0, anchor='nw', window = dynamic_widgets)
self.system_size = int(self.system_size_raw.get())
# Inverter Type
self.Lblank = Label(dynamic_widgets, text = "").grid(row=8, column=1, sticky=W)
self.L3 = Label(dynamic_widgets, text = "Inverter Type")
self.L3.grid(row=9, column=1, sticky=W)
global inverter_types # declare array as global parameter so it can be accessed outside function
inverter_types = []
for i in range(self.system_size):
inverter_list = get_inverter_list(inverter_file)
inverter_list = ["Select"] + inverter_list
self.inverter_types_raw = StringVar()
self.L3a = Label(dynamic_widgets, text = "System {}".format(i+1), font = ('Calibri', 10,'italic'))
self.L3a.grid(row=10+i, column=1, sticky=E)
self.widget = OptionMenu(dynamic_widgets, self.inverter_types_raw, *inverter_list, command = get_values_0)
self.widget.grid(row=10+i, column=2,sticky=EW)
inverter_types.append(self.widget)
dynamic_widgets.bind("<Configure>", update_scroll_region)
global inv_type
inv_type = []
def get_values_0(value):
inv_type.append(value)
button = tk.Button(root, text = "Store Values", font=('Calibri', 10,'italic'), bg = "SlateGray3",command = lambda:[gget_values_0()])
button.grid(row = 61, column = 2, columnspan=8, sticky = 'nesw')
# System Type
self.L1 = Label(root, text = "System Type")
self.L1.grid(row=4, column=1, sticky=W)
self.sys_type_raw = StringVar(root)
types = ['Select', 'Central Inverter', 'String Inverters']
self.popupMenu6 = OptionMenu(root, self.sys_type_raw, *types)
self.popupMenu6.grid(row=4, column=2, sticky=EW)
# Number of Systems
self.L2 = Label(root, text = "Number of Systems")
self.L2.grid(row=6, column=1, sticky=W)
self.system_size_raw = IntVar(root)
choices = list(range(1,50))
self.popupMenu2 = OptionMenu(root, self.system_size_raw, *choices)
self.popupMenu2.grid(row=6, column=2, sticky=EW)
self.system_size_raw.trace("w", callback)
vsb = Scrollbar(root, orient="vertical")
vsb.grid(row=8, column=6, sticky = 'ns')
canvas = Canvas(root, width = 600, height = 200)
vsb.config(command = canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
canvas.grid(row=8,column=0)
# SITE ORIENTATION
self.L12 = Label(root, text="Site Orientation:", font = ('TKDefaultFont', 9, 'bold'))
self.L12.grid(row=66, column=0, sticky=W)
self.L13 = Label(root, text = "Module Tilt Angle (degrees)")
self.L13.grid(row=67, column=1, sticky=W)
self.modtilt_raw = Entry(master)
self.modtilt_raw.grid(row=67, column=2, sticky=EW)
self.L14 = Label(root, text = "Array Azimuth (degrees)")
self.L14.grid(row=68, column=1, sticky=W)
self.arraytilt_raw = Entry(master)
self.arraytilt_raw.grid(row=68, column=2, sticky=EW)
# SUBMIT INFORMATION
self.L27 = Label(root, text=" ").grid(row=84,column=1) # Add row of space
self.cbutton = tk.Button(root, text="SUBMIT",command = self.store_user_inputs, bg = "SlateGray3")
self.cbutton.grid(row=85, column = 0, columnspan=8, sticky = 'ew')
# STORE USER INPUT
def store_user_inputs(self):
self.system_size = np.float(self.system_size_raw.get())
# save all inputs as global parameters so they can be accessed as variables outside of GUI
global params
params = [self.system_type]
root = Tk()
root.configure()
window = Window(root)
root.mainloop()
I would like to place the dynamically generated widgets (Inverter Type, Modules per String, Strings per Inverter, Inverters per System, Module Type, and Max Current per System) into a scrollable frame.
I can post more code if needed.