'How do you use columnconfigure with a scrollable frame in Tkinter?

I'm trying to create a scrollable frame where a grid manages the widgets inside of it with different weights. However, columnconfigure doesn't seem to be impacting the widgets within the scrollable frame. In this code snippet, I'm using Pmw.ScrollableFrame, but I've also tried tkscrolledframe and the code outline here: https://blog.teclado.com/tkinter-scrollable-frames/, but they all seem to be having the same issue.

from Pmw import ScrolledFrame

root = Tk()
root.state("zoomed")

Grid.columnconfigure(root, 0, weight = 4)
Grid.columnconfigure(root, 1, weight = 5)

Grid.rowconfigure(root, 0, weight = 1)
Grid.rowconfigure(root, 1, weight = 15)
Grid.rowconfigure(root, 2, weight = 3)

sf = ScrolledFrame(root)

Grid.columnconfigure(sf.interior(), index = 0, weight = 1)
Grid.columnconfigure(sf.interior(), index = 1, weight = 100)

for i in range(100):
    Button(sf.interior(), text = "button 1").grid(row = i, column = 0, sticky = 'nsew')
    Button(sf.interior(), text = "button 2").grid(row = i, column = 1, sticky = 'nsew')
    
sf.grid(row = 1, column = 0, sticky = 'nsew')

Button(root, text = "button 2").grid(row = 1, column = 1, sticky = 'nsew')
Button(root, text = "button 3").grid(row = 2, column = 0, sticky = 'nsew', columnspan = 2)
Button(root, text = "button 4").grid(row = 0, column = 1, sticky = 'nsew')

root.mainloop()

If I simply can't user columnconfigure on these types of frames, what else can I use to control the size of widgets inside a scrollable frame without hard-coding the size? Any help would be greatly appreciated!

Edit to add: I intend to populate the scrollable frame with a combination of entry boxes, check boxes, and option menus.



Solution 1:[1]

The problem isn't with columnconfigure. The problem is that the inner frame isn't expanding to fill the window.

The Pmw.ScrolledFrame class has a documented attribute horizflex which can be set to expand to have it fill the window.

horizflex Specifies how the width of the scrollable interior frame should be resized relative to the clipping frame. If 'fixed', the interior frame is set to the natural width, as requested by the child widgets of the frame. If 'expand' and the requested width of the interior frame is less than the width of the clipping frame, the interior frame expands to fill the clipping frame. If 'shrink' and the requested width of the interior frame is more than the width of the clipping frame, the interior frame shrinks to the width of the clipping frame. If 'elastic', the width of the interior frame is always set to the width of the clipping frame. The default is 'fixed'.

It sounds like you should set it to expand

sf = ScrolledFrame(root, horizflex="expand")

Solution 2:[2]

You can use the builtin function of scrolltext with a Textbox or a Frame just by changing the values. If you want to put something else you might want to use insert, delete, and StringVariable().

import tkinter

root = Tk()
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)
textbox = Text(root)
textbox.pack()
for i in range(100):
    textbox.insert(END, f"Scrolling Text Label {i}\n")
textbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=textbox.yview)
root.mainloop()

Edit: If you want detection on the scrollbar, because you are using PMW you can use the binding system which represents scrolled for this occasion.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bryan Oakley
Solution 2 Andrew Hernandez