I have a frame that is scrollable horizontally. That is working as desired. I desire the frame to vertically size itself such that all widgets are displayed. Currently, the frame will not grow as additional widgets are added, and widgets created below a certain point are not visible. I know that I could use a vertical scrollbar, but I greatly prefer not to. The frame will contain a variable amount of widgets, but never so many that it needs to be scrollable in the vertical direction. So I would prefer that it just naturally sizes itself in that direction. Here is a minimal code example:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
outer_frm = tk.Frame(root)
outer_frm.grid(column=0, row=0)
canv = tk.Canvas(outer_frm)
canv.grid(column=0, row=0)
inner_frm = tk.Frame(canv)
inner_frm.grid(column=0, row=0)
sbar = ttk.Scrollbar(outer_frm, orient='horizontal', command=canv.xview)
canv.configure(xscrollcommand=sbar.set)
sbar.grid(column=0, row=1, sticky='EW')
inner_frm.bind(
"<Configure>",
lambda e: canv.configure(
scrollregion=canv.bbox("all")
)
)
canv.create_window(
(0,0), window=inner_frm, anchor='nw'
)
for i in range(100):
for j in range(30):
tk.Label(inner_frm, text=f'-----{i}-----{j}-----').grid(column=i, row=j)
root.mainloop()
I have tried several different approaches with no success. The closest I have come is
root.update_idletasks()
width = root.winfo_width()
required_height = inner_frm.winfo_reqheight()
root.geometry(f"{width}x{required_height}")
but that only sizes the entire window, leaving the frame the same size and a window that is half empty at the bottom.
How do I go about making the frame size itself properly in the vertical direction?
Adding widgets into inner_frm
will not expand the canvas vertically. You need to expand the canvas manually when inner_frm
is resized:
def on_configure(event):
canv.configure(
scrollregion=canv.bbox('all'),
height=event.height # set height of canvas to the same as that of the frame
)
inner_frm.bind('<Configure>', on_configure)