0

I'm trying to create a scrollable widget using grid. The scrollbars are working but for some reason the inner frame is not stretching to fill the canvas.

Here is a simple (not) working example, sans the scrollbars.

import tkinter as tk

class TestFrame(tk.Frame):

    def __init__(self, master=None, cnf=None, **kw):
        super().__init__(master=master, cnf=cnf, **kw)
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)

        self.canvas = tk.Canvas(self, background='red')
        self.canvas.grid(row=0, column=0, sticky=tk.NSEW)

        self.canvas.grid_columnconfigure(0, weight=1)
        self.canvas.grid_rowconfigure(0, weight=1)

        self.inner = tk.Frame(self.canvas, background='blue')
        self.inner.grid(row=0, column=0, sticky=tk.NSEW)
        self.canvas.create_window(0, 0, anchor=tk.NW, window=self.inner)



if __name__ == "__main__":
    window = tk.Tk()
    window.geometry('500x500')

    window.grid_columnconfigure(0, weight=1)
    window.grid_rowconfigure(0, weight=1)

    testFrame = TestFrame(window)
    testFrame.grid(row=0, column=0, sticky=tk.NSEW)

    window.mainloop()

When you run it, you can see that the red canvas fills the entire window but the blue frame is nowhere to be seen. Even when content is added to the frame, it only stretches to accommodate the child widgets.

What am I not understanding about tkinter's grid layout manager?

Thanks in advance for your help.

Brent Parker
  • 709
  • 1
  • 5
  • 19
  • @stovfl Yes, that works, but it seems kinda hacky. I would like to learn why the grid layout manager works correctly for the canvas but not for the inner frame. The code is nearly identical. So what are the limitations of the layout manager? – Brent Parker Jan 01 '20 at 11:02
  • ***"the grid layout manager works correctly for the canvas but not for the inner frame"***: You didn't use `.grid(...` you layout the `Frame` with `.create_window(...`. – stovfl Jan 01 '20 at 11:05
  • I'm rather new to Tkinter so perhaps I'm a bit confused. In the documentation, using Canvas.create_window() puts a widget inside the canvas and allows canvas to act as the layout manager. Does that mean Canvas does not use grid for widgets placed inside it? Is there a way to tell the canvas to do so? Or if I want to use scrollbars is there another widget other than Canvas that would be more appropriate? – Brent Parker Jan 01 '20 at 11:10
  • you can't use `grid`/`place`/`pack` to put elements on Canvas - it wasn't created for `Canvas` and it will not work. You would have to create own layout manager but it is too complex. – furas Jan 01 '20 at 11:22
  • examples of [ScrolledFrame and ScrolledCanvas](https://github.com/furas/python-examples/tree/master/tkinter/scrolled-frame-canvas) – furas Jan 01 '20 at 11:25
  • @stovfl: using a frame in a canvas isn't the only way to scroll a group of widgets. It's the most common way, but not the only way. For example, you can embed widgets in a `Text` widget, or you can use `place` for the widgets and manage all of the scrolling yourself. – Bryan Oakley Jan 01 '20 at 15:21

0 Answers0