0

I want to create multiple "scrollable frames" in another "scrollable frame".

The "scrollable frame" I am talking about is a little hack around thing that I took from Codemy.com : https://youtu.be/0WafQCaok6g

When I create them one by one like the code below, everything works.

from tkinter import *
from tkinter import ttk

window = Tk()
window.attributes('-zoomed', True)
screen_width = window.winfo_screenwidth()

main_frame = Frame(window)
main_frame.pack(fill=BOTH, expand=YES)

my_main_canvas = Canvas(main_frame)
my_main_canvas.pack(side=LEFT, fill=BOTH, expand=YES)
my_main_scrollbar = ttk.Scrollbar(main_frame, orient=VERTICAL, command=my_main_canvas.yview)
my_main_scrollbar.pack(side=RIGHT, fill=Y)
my_main_canvas.configure(yscrollcommand=my_main_scrollbar.set)
my_main_canvas.bind('<Configure>', lambda e: my_main_canvas.configure(scrollregion = my_main_canvas.bbox("all")))
new_main_frame = Frame(my_main_canvas, relief=SUNKEN)
my_main_canvas.create_window((0,0), window=new_main_frame, anchor="center", width=screen_width-30)




frame1 = Frame(new_main_frame)
frame1.pack(fill=X, pady=10)
my_canvas1 = Canvas(frame1)
my_canvas1.pack(side=TOP, fill=BOTH, expand=YES)
my_scrollbar1 = ttk.Scrollbar(frame1, orient=HORIZONTAL, command=my_canvas1.xview)
my_scrollbar1.pack(side=BOTTOM, fill=X)
my_canvas1.configure(xscrollcommand=my_scrollbar1.set)
my_canvas1.bind('<Configure>', lambda e: my_canvas1.configure(scrollregion = my_canvas1.bbox("all")))
second_frame1 = Frame(my_canvas1, relief=SUNKEN)
my_canvas1.create_window((0,0), window=second_frame1, anchor="center")
for i in range (100):
    Label(second_frame1, text=f"Label {i+1}").grid(row=0, column=i)


frame2 = Frame(new_main_frame)
frame2.pack(fill=X, pady=10)
my_canvas2 = Canvas(frame2)
my_canvas2.pack(side=TOP, fill=BOTH, expand=YES)
my_scrollbar2 = ttk.Scrollbar(frame2, orient=HORIZONTAL, command=my_canvas2.xview)
my_scrollbar2.pack(side=BOTTOM, fill=X)
my_canvas2.configure(xscrollcommand=my_scrollbar2.set)
my_canvas2.bind('<Configure>', lambda e: my_canvas2.configure(scrollregion = my_canvas2.bbox("all")))
second_frame2 = Frame(my_canvas2, relief=SUNKEN)
my_canvas2.create_window((0,0), window=second_frame2, anchor="center")
for i in range (100):
    Label(second_frame2, text=f"Label {i+1}").grid(row=0, column=i)


frame3 = Frame(new_main_frame)
frame3.pack(fill=X, pady=10)
my_canvas3 = Canvas(frame3)
my_canvas3.pack(side=TOP, fill=BOTH, expand=YES)
my_scrollbar3 = ttk.Scrollbar(frame3, orient=HORIZONTAL, command=my_canvas3.xview)
my_scrollbar3.pack(side=BOTTOM, fill=X)
my_canvas3.configure(xscrollcommand=my_scrollbar3.set)
my_canvas3.bind('<Configure>', lambda e: my_canvas3.configure(scrollregion = my_canvas3.bbox("all")))
second_frame3 = Frame(my_canvas3, relief=SUNKEN)
my_canvas3.create_window((0,0), window=second_frame3, anchor="center")
for i in range (100):
    Label(second_frame3, text=f"Label {i+1}").grid(row=0, column=i)


window.mainloop()

My problem comes now. I don't know in advance how many of those scrollable frames I will use. Therefore, I use a for loop to create them (code below). However, the scrollable frames don't display properly their content (except the last one).

from tkinter import *
from tkinter import ttk

window = Tk()
window.attributes('-zoomed', True)
screen_width = window.winfo_screenwidth()

main_frame = Frame(window)
main_frame.pack(fill=BOTH, expand=YES)

my_main_canvas = Canvas(main_frame)
my_main_canvas.pack(side=LEFT, fill=BOTH, expand=YES)
my_main_scrollbar = ttk.Scrollbar(main_frame, orient=VERTICAL, command=my_main_canvas.yview)
my_main_scrollbar.pack(side=RIGHT, fill=Y)
my_main_canvas.configure(yscrollcommand=my_main_scrollbar.set)
my_main_canvas.bind('<Configure>', lambda e: my_main_canvas.configure(scrollregion = my_main_canvas.bbox("all")))
new_main_frame = Frame(my_main_canvas, relief=SUNKEN)
my_main_canvas.create_window((0,0), window=new_main_frame, anchor="center", width=screen_width-30)




for i in range(3):
    frame = Frame(new_main_frame)
    frame.pack(fill=X, pady=10)
    my_canvas = Canvas(frame)
    my_canvas.pack(side=TOP, fill=BOTH, expand=YES)
    my_scrollbar = ttk.Scrollbar(frame, orient=HORIZONTAL, command=my_canvas.xview)
    my_scrollbar.pack(side=BOTTOM, fill=X)
    my_canvas.configure(xscrollcommand=my_scrollbar.set)
    my_canvas.bind('<Configure>', lambda e: my_canvas.configure(scrollregion = my_canvas.bbox("all")))
    second_frame = Frame(my_canvas, relief=SUNKEN)
    my_canvas.create_window((0,0), window=second_frame, anchor="center")
    for i in range (100):
        Label(second_frame, text=f"Label {i+1}").grid(row=0, column=i)
    

window.mainloop()

Sorry for not showing you screenshots, but Stack Overflow is not letting me embed images in my questions for now.

If you're willing to help me and want to see what the problem looks like, I invite you to directly run the code on your computer.

For those on Windows, replace window.attributes('-zoomed', True) by window.state("zoomed")

I think the problem comes from using the sames variable names for each iteration of the for loop, so I tried storing them differently with a list of dictionnaries, but it wouldn't work either.

Thanks for helping

Val
  • 1

0 Answers0