动态创建的小部件的滚动条-Python Tkinter

时间:2019-12-17 15:15:32

标签: python-3.x tkinter scrollbar

我有一个GUI,它可以根据用户选择的系统数量动态生成窗口小部件:

GUI

这些小部件是使用回调函数(如以下代码示例)生成的:

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()

我想将动态生成的小部件(逆变器类型,每个字符串的模块,每个逆变器的字符串,每个系统的逆变器,模块类型和每个系统的最大电流)放置在可滚动的框架中。

如果需要,我可以发布更多代码。

1 个答案:

答案 0 :(得分:0)

可以通过在Frame上创建Canvas小部件来创建可滚动框架。一个例子如下:

vsb = Scrollbar(root, orient = VERTICAL)
vsb.pack(fill=Y, side = RIGHT, expand = FALSE)
canvas = Canvas(root, yscrollcommand=vsb.set)
canvas.pack(side=LEFT, fill=BOTH, expand=TRUE)
vsb.config(command = canvas.yview)
canvas.config(scrollregion = canvas.bbox("all"))
InverterType = Frame(canvas)
canvas.create_window(0, 0, anchor = NW, window = InverterType)

现在,确保将在callback函数中创建的所有小部件添加到此InverterType框架中。

提示-将root替换为InverterType