Using the Pack Layout Manager in Tkinter
Laying out widgets with the Pack layout manager

Getting started with TKinter

Heads up! You've already completed this tutorial.

In this tutorial, we will take a look at how to make a login UI. Today's tutorial will focus on how to use the Tkinter's pack layout manager.

Designing The UI

What is a layout manager? When you create graphical interfaces, the widgets in the window must have a way to be arranged relative to each other. For example, placing widgets can be accomplished using their relative positions to other widgets or by defining their positions by specifying pixel locations. In Tkinter there are three types of layout managers -- pack, place, and grid. Each manager uses a different method to help us arrange widgets. To find out more about the differences between the three methods, please check out this tutorial.

Layout for login UI, turquoise background Layout of login UI created in this tutorial using Tkinter.

Login UIs are everywhere, on your phone, computer, at the bank, and more. It is essential to gather a user's information and check if the input matches data which is already in the system.

Take a look at the image of the login UI above. We'll need to create a label to display the text "Login". Then, add the user's personal image. Next are the fields where they can enter their username, password, and check a box if they want the computer to remember their information for the next time. Since it is beyond the scope of this tutorial, the "Forgot password" link is simply a placeholder.

Pack Layout Manager

So what is pack? The simplest way to think about it is that the pack() method turns each individual widget into a block. Each widget has its own size and the pack manager fits them all together just like you would do with real blocks.

Each widget already has its own size and parameters. Of course, you can change these to better fit your needs. Once every widget's size is determined, the manager does its job to arrange them in the window.


Let's take a moment to learn some of the basics of the pack layout manager. With pack, the manager stacks widgets on top of each other vertically like blocks. Of course, you can also achieve a horizontal layout by changing the side parameter to 'left' or 'right'. You can also change the height, width, and locations of the widgets. Some of the pack manager's more useful parameters are listed below:

  • side -- specifies the general location of the widget in the window, arguments are 'top', 'bottom', 'left', 'right' (default is 'top').
  • fill -- which directions you want the widget to fill in the parent window, can choose 'x''y' directions, or 'both'
  • padx, pady -- the number of pixels surrounding the widget to create a padding between other widgets, for horizontal or vertical padding.
  • ipadx, ipady -- how many pixels to use for padding inside the widget, also for horizontal or vertical padding
  • expand -- set to True if you want the widget to stretch if the parent window expands. Default is False
  • anchor -- where the widget is placed in the parent widget, specified by  'n', 's', 'e', 'w', or some combination of them. Default is 'center'.

Create A Simple UI With Pack

The geometry manager pack is very useful for general case GUIs. Below is a simple example of how to create a UI and arrange widgets in the window with pack().

python
from tkinter import *

root = Tk()
root.title("Using Pack")
root.geometry("300x100")  # set starting size of window
root.config(bg="skyblue")

# Example of how to arrange Button widget using pack
button1 = Button(root, text="Click me")
button1.pack(side="left")

# Example of how to arrange Label widgets using pack
label1 = Label(root, text="Read me", bg="skyblue")
label1.pack(side="right")
label2 = Label(root, text="Hello", bg="purple")
label2.pack(side="right")

def toggled():
    '''display a message to the terminal every time the check button
    is clicked'''
    print("The check button works.")

# Example of how to arrange Checkbutton widget using pack
var = IntVar()  # Variable to check if checkbox is clicked, or not
check = Checkbutton(root, text="Click me", bg="skyblue", command=toggled, variable=var)
check.pack(side="bottom")
root.mainloop()

First, let's import the Tkinter module and create the main root window in lines 1-6.

Example of how pack can arrange widgets Example of how pack can arrange widgets.

In lines 9-10, we create the first Button widget. Notice how the widget is arranged on the left of the window using the side="left"argument in line 10. Next, let's see what happens if we want to place widgets on the right (lines 14-17). Here we arrange two labels in the window using side="right". Notice how label2 is placed to the right of label1. In order to place label2 under label1 you would need to create a Frame widget to contain them. Keep in mind that if you use pack with a complex GUI your code can get more complex as well. An example of this can be seen below with the login UI.

Finally, let's look at the Checkbutton on the bottom. Pack automatically centers widgets in their respective areas. Changing the anchor value to 'w' can help to move the checkbox to the left a little bit.

Creating The Login UI

Now let's get to the login UI! The following is the entire code for the GUI.

python
from tkinter import *

root = Tk()
root.title("Login UI using Pack")
root.geometry("400x320")  # set starting size of window
root.maxsize(400, 320)  # width x height
root.config(bg="#6FAFE7")  # set background color of root window

login = Label(root, text="Login", bg="#2176C1", fg='white', relief=RAISED)
login.pack(ipady=5, fill='x')
login.config(font=("Font", 30))  # change font and size of label

# login image
image = PhotoImage(file="redhuli_favicon.gif")
img_resize = image.subsample(5,5)
Label(root, image=img_resize, bg="white", relief=SUNKEN).pack(pady=5)

def checkInput():
    '''check that the username and password match'''
    usernm = "Username301"
    pswrd = "Passw0rd"
    entered_usernm = username_entry.get()  # get username from Entry widget
    entered_pswrd = password_entry.get()  # get password from Entry widget

    if (usernm == entered_usernm) and (pswrd == entered_pswrd):
        print("Hello!")
        root.destroy()  

    else:
        print("Login failed: Invalid username or password.")

def toggled():
    '''display a message to the terminal every time the check button
    is clicked'''
    print("The check button works.")

# Username Entry
username_frame = Frame(root, bg="#6FAFE7")
username_frame.pack()

Label(username_frame, text="Username", bg="#6FAFE7").pack(side='left', padx=5)

username_entry = Entry(username_frame, bd=3)
username_entry.pack(side='right')

# Password entry
password_frame = Frame(root, bg="#6FAFE7")
password_frame.pack()

Label(password_frame, text="Password", bg="#6FAFE7").pack(side='left', padx=7)

password_entry = Entry(password_frame, bd=3)
password_entry.pack(side='right')

# Create Go! Button

go_button = Button(root, text="GO!", command=checkInput, bg="#6FAFE7", width=15)

go_button.pack(pady=5)

# Remember me and forgot password
bottom_frame = Frame(root, bg="#6FAFE7")
bottom_frame.pack()

var = IntVar()

remember_me = Checkbutton(bottom_frame, text="Remember me", bg="#6FAFE7", command=toggled, variable=var)
remember_me.pack(side='left', padx=19)

# The forgot password Label is just a placeholder, has no function currently
forgot_pswrd = Label(bottom_frame, text="Forgot password?", bg="#6FAFE7")
forgot_pswrd.pack(side="right", padx=19)

root.mainloop()

The pack layout manager works best for simple layouts. The login UI consists mostly of a few vertical widgets stacked on top of each other. So this is a perfect opportunity to experiment with pack().

Begin by setting up the root window, its size and background color. Then the first two widgets, the login Label and user image, are created and placed in the root window. These two are the easiest since they are simply two widgets arranged vertically.

For the username, password, and "Remember me" areas, these are a little more complex. Because they are each sets of two different widgets each arranged horizontally, AND because we already have the login and image widgets arranged vertically, we need to create a Frame widget for each one. These frames will also be stacked under the widgets we already created. Each Frame will hold two widgets.

Let's take a look at the first one. In line 38, we create the username_frame object that will contain both the "username" text and the Entry widget for usernames to type in their name. You'll create these in lines 43-44. Notice how the side arguments are 'left' and 'right' to arrange them horizontally in username_frame. The other two areas we create in a similar fashion. I won't include their description here since it is similar.

After the user types in their information and clicks the "GO!" button, we call checkInput() (lines 18 -- 30) to check if the information entered by the user matches what is already stored in our program on lines 20 and 21. If they match, then the window closes by calling root.destroy().

Login UI with Red Huli logo, blue background. Example UI created with Tkinter and Python Login UI created using Tkinter and Python.

Summary

In this tutorial, we looked at how to use the pack method by creating two separate UIs. We also look at the how to arrange widgets in both simple and slightly more complex layouts.

Of course there are still tons of ways to improve the look and functionality of this GUI. For one thing, you could actually allow the user to create their own username and password, and write that information to an output file. Another thing you could do is allow the UI to store the user's information using the "Remember me" Checkbutton. Also, you could change the "Forgot password" Label into a link that redirects the user to a new window. Furthermore, you could let the user select their own image for their profile by searching for a local file on their computer.

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Using the Pack Layout Manager in Tkinter was written by Joshua Willman .

Interested in contributing to the site? Find out more.