Search code examples
pythontkinterscrollframe

How to store and add horizontal frames within a scrollable frame using tkinter?


design I am aiming for

I am trying to implement a design like this, where you have a canvas inside a frame which is scrollable, so I can have alot of different entries in the frame. I have added the code I have currently. The listbox was simply a test and I will not be using the listbox. I basically need a way to store lots of horizontal frames within the scrollbar frame I think, that can hold a canvas to display the image, and some buttons/labels. The code I have currently means the scrollable frame window is very small so I need to know how to enlarge this and how to make it so I can store as many frames as I need within the scrollable one. Thank you

    customisationWindow = tk.Toplevel(mainWindow)
    customisationWindow.geometry("700x580")
    customisationWindow.title("DIY Store Quote System")
    tabControl = ttk.Notebook(customisationWindow)

    tab1 = ttk.Frame(tabControl, width=300)
    tab1.pack(fill="both", expand=1)
    tab2 = ttk.Frame(tabControl)
    tab3 = ttk.Frame(tabControl)
    tab4 = ttk.Frame(tabControl)
    tab5 = ttk.Frame(tabControl)

    tabControl.add(tab1, text='Select Wallpaper')
    tabControl.add(tab2, text='Select Colour')
    tabControl.add(tab3, text='Select Detailing')
    tabControl.add(tab4, text='Add Adhesive/Lining')
    tabControl.add(tab5, text='View Basket')
    tabControl.pack(expand=1, fill="both")
    createTab1(tab1)
    createTab2(tab2)
    createTab3(tab3)
    createTab4(tab4)
    createTab5(tab5)


def createTab5(tab):

    yourBasketLabel = Label(tab, text="Your Basket", bg="#94B3BD",
                        font=("Times New Roman", 14)).place(x=50, y=50)

    basketFrame = Frame(tab, width=550, height=400)
    basketFrame.place(x=50, y=70)
    basketCanvas = Canvas(basketFrame, width=550, height=400)
    basketCanvas.place(x=50, y=70)
    scrollbar = Scrollbar(basketCanvas)
    scrollbar.pack(side=RIGHT, fill=Y)
    
    mylist = Listbox(basketFrame, yscrollcommand=scrollbar.set)
    for line in range(100):
        mylist.insert(END, "This is line number " + str(line))

    mylist.pack(side=LEFT, fill=BOTH)
    scrollbar.config(command=mylist.yview)


mainWindow = Tk()
mainFrame = Frame(mainWindow, bg="#94B3BD")
mainFrame.pack(fill="both", expand=True)
verticalFrame = Frame(mainFrame, bg="#94B3BD")

mainWindow.geometry("500x200")

welcomeMessage = tk.Label(verticalFrame, text="Welcome to the DIY Store Quote System", background="#94B3BD",
                          pady=40, font=("Arial", 25)).pack()
startButton = tk.Button(verticalFrame, highlightbackground='#B1E4EC', text="Begin Customising Wallpaper",
                        font=("Arial", 25),
                        pady=20, command=open).pack()
verticalFrame.pack()

mainWindow.mainloop()


Solution

  • You can add a scrollbar to the canvas and then add a frame into the canvas with create_window. You can then add more frames to myList.

    def createTab5(tab):
    
        yourBasketLabel = Label(tab, text="Your Basket", bg="#94B3BD",
                            font=("Times New Roman", 14)).place(x=50, y=50)
    
        basketFrame = Frame(tab, width=550, height=400)
        basketFrame.place(x=50, y=70)
        basketCanvas = Canvas(basketFrame, width=550, height=400)
        basketCanvas.pack(fill = "both", expand = True, side = "left")
        scrollbar = Scrollbar(basketFrame, command = basketCanvas.yview)
        scrollbar.pack(side=RIGHT, fill=Y)
        basketCanvas.config(yscrollcommand = scrollbar.set)
        basketCanvas.bind("<Configure>", resizeCanvas)
        myList = tk.Frame(basketCanvas)
        basketCanvas.create_window((4,4), window = myList, anchor = "nw")
        for line in range(100):
            frame = tk.Frame(myList)
            frame.pack()
            label = tk.Label(frame, text = "This is line number {}".format(str(line)))
            label.pack()
        scrollbar.config(command=basketCanvas.yview)
    
    def resizeCanvas(event):
        canvas = event.widget
        canvas.update_idletasks()
        canvas.config(scrollregion = canvas.bbox("all"))