Search code examples
pythontkinter

Does the rule against mixing geometry managers in TKinter apply even across scopes?


The general advice I have seen everywhere is that you should never mix geometry managers in TKinter (i.e. you should never mix .grid() with .pack() ). I am not sure what else to do, though, and I'm not sure if that adage applies in my present circumstance.

I am making an application with many widgets laid out in a grid like so:

sketch of some boxes in a relatively simple grid

Some of these widgets need to be horizontally scrollable. That means that some of these cells contain a LabelFrame which itself contains a Canvas and a Scrollbar.

I want the LabelFrame divided up like so:

a vertically stacked box and scrollbar

It really seems like grid is the right manager for the more foundational structure: the items are in a grid and replicating the layout with pack is taking a lot of extra frames and thinking about what order to do things in and how to 'trick' things into having the right sizes.

But it also really seems like pack is the right manager for the internal structures, at least for the scrollbars, because I want them across the entire bottom of the frame with the canvas across the entire rest of the frame on top of them. I'm trying to replicate that with grid right now using a single column with two rows and it's not working-- the relative size is off and also the scrollbar keeps disappearing either under the canvas or somewhere else off-screen.

Of course, mixing them also isn't working presently, but I figured maybe I'd ask what the correct approach is before I start delving into something that may well be a bad idea.


Solution

  • You can mix the use of pack, place, and grid within an application as a whole, and I would argue that it's a best practice to do so. The only rule is that you can't mix them with widgets that share the same parent.

    In your case it's perfectly fine to put a canvas and a scrollbar inside a frame using pack, and to put that frame inside the main window or inside another frame using grid.