Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Controlling Layout With Geometry Managers

00:00 Controlling Layout with Geometry Managers Up to this point, you’ve been adding widgets to windows and Frame widgets using ,pack(), but you’ve not learned exactly what this method does, so let’s change that now.

00:14 Application layout in Tkinter is controlled with geometry managers. While .pack() is an example of a geometry manager, it’s not the only one.

00:23 Tkinter has two others: .place() and .grid(). Each window or frame in your application can use only one geometry manager, but different frames can use different geometry managers even if they’re assigned to a frame or window using another geometry manager.

00:40 Let’s start by taking a closer look at .pack(). The .pack() geometry manager uses a packing algorithm to place widgets in a frame or window in a specified order. For a given widget, the packing algorithm has two primary steps.

00:56 Firstly, compute a rectangular area called a parcel that’s just tall or wide enough to hold the widget and fills the remaining width or height in the window with blank space.

01:07 Secondly, center the widget in the parcel unless a different location has been specified. .pack() is powerful, but it can be difficult to visualize, so the best way to get a feel for it is to look at some examples.

01:21 Let’s see what happens when you pack three label widgets into a frame.

01:27 First, a red frame is created with a width and height of 200,

01:35 followed by smaller yellow

01:42 and blue frames.

01:52 .pack() places each frame below the previous one by default in the order they’re assigned to the window. Each frame is placed at the topmost available position.

02:01 Therefore, the red frame is placed at the top of the window. This is followed by the yellow frame and then the blue one. There are three invisible parcels, each containing one of the three Frame widgets.

02:14 Each parcel is as wide as the window and as tall as the frame that it contains. Because no anchor point was specified when .pack() was called for each frame, they’re all centered inside of their parcels and that’s why each frame is centered in the window.

02:32 .pack() accepts some keyword arguments for more precisely configuring widget placement. For example, you can set the fill keyword argument to specify which direction the frame should fill.

02:43 The options are tk.X to fill in the horizontal direction, tk.Y to fill vertically, and tk.BOTH to fill in both directions.

02:54 Here’s how the code you just saw is modified to stack the three frames so that each one fills the window horizontally. The width is removed, and then .pack() is set to fill horizontally using tk.X.

03:09 This is then repeated for the other two frames. Notice that the width is not set on any of the Frame widgets. Width is no longer necessary because each frame sets .pack() to fill horizontally, overriding any width you may set.

03:28 You can see the window produced by this script on screen and note that on both macOS and Linux, you may need to expand the initial window, which may be very narrow to start with.

03:39 One of the nice things about filling the window with .pack() is that the fill is responsive to window resizing. Try changing the width of the window to see how this works, but note that the frame widgets don’t expand in the vertical direction.

03:57 The side keyword argument to .pack() specifies on which side of the window the widgets should be placed. You can see the available options on screen.

04:05 If you don’t set side, then pack will automatically use tk.TOP and place new widgets at the top of the window or the topmost portion of the window that isn’t already occupied by a widget.

04:17 To see this in action, take the contents of the original three frame script and modify it as seen to place a three frame side by side from left to right expanding each frame to fill the window vertically.

04:30 The height of the first frame is altered and then fill and side added to .pack().

04:38 This is then repeated for the other two frames, although both have their height removed.

04:49 This time, you have to specify the height keyword argument on at least one of the frames to force the window to have some height. You can see the result of this script on screen. Just as when you set the fill to tk.X to make the frames responsive to horizontal resizing, here you’ll see they’re responsive to vertical resizing.

05:10 To make this script fully responsive, you’ll need to set the fill keyword argument of .pack() to tk.BOTH, set the expand keyword argument to true and repeat this for the other frames.

05:41 When you run this script, you’ll see a window that initially looks the same, but you’ll notice that it responds to resizing both in the horizontal and vertical directions.

05:54 In the next section of the course, you’ll take a look at Tkinter’s other geometry managers .place() and .grid().

Become a Member to join the conversation.