0

I've always found the pack() geometry manager quite ambiguous in terms of how it acts when widgets are added. Here I have a simple code for creating a new frame within a much bigger parent frame. The frame size has been set to 300x300. The problem is that if I create a label with the pack() geometry manager within this frame, it will suppress the original frame size. Basically the frame will become as big as is the label. If I use the place() geometry manager, then there is no problem and the frame stays at the original 300x300 size.

The question is - why does packing a label within the frame affects its size? And then what is the best way to avoid this problem and have everything fixed at the size as they are set?

class MainRightFrame(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.place(x=600, y=0)
        self.config(height=300, width=300, bg='green')

        label = Label(self, text='Left Frame')
        label.place(x=10, y=10)      # OPTION 1
        # label.pack()               # OPTION 2
Kārlis Rieksts
  • 169
  • 1
  • 1
  • 8
  • Possible duplicate of [How to set a tkinter window to a constant size](https://stackoverflow.com/questions/36575890/how-to-set-a-tkinter-window-to-a-constant-size) – stovfl Mar 24 '19 at 20:49
  • _"I've always found the pack() geometry manager quite ambiguous in terms of how it acts when widgets are added."_ - it's behavior is well defined and deterministic, though it's not documented well in the tkinter world. Here is a link to the canonical documentation: http://tcl.tk/man/tcl8.5/TkCmd/pack.htm#M26 – Bryan Oakley Mar 25 '19 at 03:07

2 Answers2

0

To fix this, add the following line after the line beginning: self.config(...:

self.pack_propagate(0)

See here for a documentary explaining this.

As @KārlisRieksts noted, this approach does not work however if the frame (or other parent widget) is packed with place() geometry manager. The child widgets will then affect the size of the parent.

Artemis
  • 2,553
  • 7
  • 21
  • 36
0

why does packing a label within the frame affects its size?

Because that is how the packer is designed to work. It will shrink or grow to fit its contents, which is what you want 99.99% of the time.

For the canonical documentation for how pack works, see the official tcl/tk documentation here:

The packer algorithm

And then what is the best way to avoid this problem and have everything fixed at the size as they are set?

The best wait to avoid this "problem" is to use place. However, the way both pack and grid works makes it much easier then using place to create a responsive UI that can handle changes in font size, resolution, and the user manually resizing the window.

In over a couple decades of writing GUIs with python/tkinter and tcl/tk, I have never used place except for extremely special circumstances. Its simply too difficult to use for must common layouts.

If you absolutely insist on using pack or grid without this "shrink to fit" behavior, you can pass a false value to the pack_propagate or grid_propagate method of the containing frame (eg: self.pack_propagate(False)). In my experience this is very rarely the right solution.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685