kakyo
kakyo

Reputation: 11600

In what cases Tkinter's grid() cannot be mixed with pack()?

I want to eliminate strange extra space that seems to resist any size tweaking in my layout when using grid() alone, but calling in pack() sometimes make things worse: The GUI simply disappear entirely!

I read a few eye-opening layout answers from @Bryan Oakley such as:

When to use pack or grid layouts in tkinter?

and

Tkinter: grid or pack inside a grid?

but when I get down to write my own stuff, I still often have troubles.

My understanding:

  1. I must have a Frame to fill the root window, otherwise there'd be no hope to fill the extra space in the window, however I tweak widgets alone.
  2. For all the child widgets sitting inside a common parent Frame, I must use either pack() or grid() but not both.
  3. When using grid() in a Frame, it's mandatory to specify Frame.grid_rowconfigure() and .grid_columnconfigure() with non-zero weight arguments. Otherwise, nothing would show up.
  4. It's thus possible to have the main Frame using pack(), but its immediate child Frames all using grid(); Inside each of these child Frames on the grid, we could then pack() their own child widgets. In other words, we could interleave grid() and pack() by "regions" or container hierarchy levels, but never mix them in the same container: The only restriction.
  5. By a careful weight design, I could fill a horizontal space in a parent Frame with a child Frame full of widgets laid out horizontally, e.g., all widgets use grid(sticky='nsew'), and the child Frame uses pack(side='top', fill='both', expand=True).

If my understanding was correct, then I could never figure out why #5 couldn't work for me, e.g., there is always unused extra space towards the right end of my horizontal child Frame inside the main Frame of the root window.

UPDATE 2

I figured it out. #5 didn't work for me because I forgot to specify .grid_columnconfigure(0, weight=1) in the main Frame before using grid(). My bad! Case closed.

UPDATE

I'm on macOS High Sierra, running python 3.6.4 Homebrew.

Upvotes: 1

Views: 1600

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385980

In what cases Tkinter's grid() cannot be mixed with pack()?

In all cases, you cannot use both grid and pack for widgets that have a common master. Within a master, all direct children must use the same geometry manager. Within an application as a whole, you can mix pack and grid all you want as long as you follow that one rule that you can't use them both for widgets that have the same parent.

  1. I must have a Frame to fill the root window, otherwise there'd be no hope to fill the extra space in the window, however I tweak widgets alone.

This is not correct. You can easily fill all of the space in the root window without using a frame.

  1. For all the child widgets sitting inside a common parent Frame, I must use either pack() or grid() but not both.

That is correct. The third option is to use place, though it's rarely the best choice.

  1. When using grid() in a Frame, it's mandatory to specify Frame.grid_rowconfigure() and .grid_columnconfigure() with non-zero weight arguments. Otherwise, nothing would show up.

That is not true -- configuring rows and columns to have a non-zero weight isn't mandatory. It's usually a best practice, but it's not required in order for widgets to show up. The weight only applies to how grid manages extra space. Any widgets with a non-zero size should appear whether you use weights or not.

  1. It's thus possible to have the main Frame using pack(), but its immediate child Frames all using grid()

Correct.

  1. By a careful weight design, I could fill a horizontal space in a parent Frame with a child Frame full of widgets laid out horizontally, e.g., all widgets use grid(sticky='nsew'), and the child Frame uses pack(side='top', fill='both', expand=True).

That is correct.

Upvotes: 3

Related Questions