GUI User Input and Arranging Widgets

CS 65: Introduction to Computer Science I

tkinter's Entry widget

The Entry widget provides a text box that allows the user to type in a short bit of text.

This is one way to get input from your user

  • An Entry is for input
  • A Label is for output - it can't be changed by the user

When creating an Entry widget, you initialize it with its parent window and how wide the input box should be.

In [ ]:
self.my_entry = tkinter.Entry(self.main_window, width=10)

Whenever you want to use the input that the user typed into an Entry, use the Entry's get() method, which returns the text as a string.

In [ ]:
#You probably want to do this inside a callback function
user_input = self.my_entry.get() #this will be a string

A conversion calculator example

In [1]:
import tkinter

class KilometersToMilesGUI:
    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()

        # Create the widgets
        self.prompt_label = tkinter.Label(self.main_window, text="Enter a distance in kilometers:")
        self.kilo_entry = tkinter.Entry(self.main_window, width=10)
        self.answer_label = tkinter.Label(self.main_window, text="Converted to miles:")
        self.calc_button = tkinter.Button(self.main_window, text="Convert", command=self.convert)

        # Pack the widgets.
        self.prompt_label.pack()
        self.kilo_entry.pack()
        self.answer_label.pack()
        self.calc_button.pack()

        # Enter the tkinter main loop.
        tkinter.mainloop()

    # The convert method is a callback function for
    # the Calculate button.
    def convert(self):
        # Get the value entered by the user into the
        # kilo_entry widget.
        kilo = float(self.kilo_entry.get())

        # Convert kilometers to miles.
        miles = kilo * 0.6214

        # Convert miles to a string and create
        # the string for the new text to appear
        # on the answer label
        new_text = "Converted to miles: {mi:.2f}".format(mi=miles)
        self.answer_label.config(text=new_text)


# Create an instance of the KilometersToMilesGUI class.
kilo_conv = KilometersToMilesGUI()

Using the side argument when packing

When calling pack() for any widget, you can give it the optional side argument to tell it which part of the window you want it anchored towards (default is top)

  • side="top"
  • side="bottom"
  • side="left"
  • side="right"
In [1]:
import tkinter

class KilometersToMilesGUI:
    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()
        self.main_window.title("km to mi calculator")
        self.main_window.geometry("600x300")

        # Create the widgets
        self.prompt_label = tkinter.Label(self.main_window, text="Enter a distance in kilometers:")
        self.kilo_entry = tkinter.Entry(self.main_window, width=10)
        self.answer_label = tkinter.Label(self.main_window, text="Converted to miles:")
        self.calc_button = tkinter.Button(self.main_window, text="Convert", command=self.convert)

        # Pack the widgets.
        self.prompt_label.pack(side="top")
        self.kilo_entry.pack(side="left")
        self.answer_label.pack(side="right")
        self.calc_button.pack(side="bottom")

        # Enter the tkinter main loop.
        tkinter.mainloop()

    # The convert method is a callback function for
    # the Calculate button.
    def convert(self):
        # Get the value entered by the user into the
        # kilo_entry widget.
        kilo = float(self.kilo_entry.get())

        # Convert kilometers to miles.
        miles = kilo * 0.6214

        # Convert miles to a string and create
        # the string for the new text to appear
        # on the answer label
        new_text = "Converted to miles: {mi:.2f}".format(mi=miles)
        self.answer_label.config(text=new_text)


# Create an instance of the KilometersToMilesGUI class.
kilo_conv = KilometersToMilesGUI()

Using the padx and pady arguments when packing

You can also send optional padx and pady arguments to pack() which control how much horizontal or vertical space to pad around the widget.

In [1]:
import tkinter

class KilometersToMilesGUI:
    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()
        self.main_window.title("km to mi calculator")
        self.main_window.geometry("600x300")

        # Create the widgets
        self.prompt_label = tkinter.Label(self.main_window, text="Enter a distance in kilometers:")
        self.kilo_entry = tkinter.Entry(self.main_window, width=10)
        self.answer_label = tkinter.Label(self.main_window, text="Converted to miles:")
        self.calc_button = tkinter.Button(self.main_window, text="Convert", command=self.convert)

        # Pack the widgets.
        self.prompt_label.pack(side="left", padx=20)
        self.kilo_entry.pack(side="left", padx=20)
        self.answer_label.pack(side="bottom", pady=20)
        self.calc_button.pack(side="bottom")

        # Enter the tkinter main loop.
        tkinter.mainloop()

    # The convert method is a callback function for
    # the Calculate button.
    def convert(self):
        # Get the value entered by the user into the
        # kilo_entry widget.
        kilo = float(self.kilo_entry.get())

        # Convert kilometers to miles.
        miles = kilo * 0.6214

        # Convert miles to a string and create
        # the string for the new text to appear
        # on the answer label
        new_text = "Converted to miles: {mi:.2f}".format(mi=miles)
        self.answer_label.config(text=new_text)


# Create an instance of the KilometersToMilesGUI class.
kilo_conv = KilometersToMilesGUI()

Using Frames

A Frame is like a sub-window that you can use to organize your widgets.

In the example below, the main_window only directly contains three widgets: top_frame, middle_frame, and bottom_frame.

All other widgets are placed in one of the frames instead of the main window.

In [1]:
import tkinter

class KilometersToMilesGUI:
    def __init__(self):

        # Create the main window.
        self.main_window = tkinter.Tk()
        self.main_window.title("km to mi calculator")
        self.main_window.geometry("600x300")
        
        # Create the frames
        self.top_frame = tkinter.Frame(self.main_window)
        self.middle_frame = tkinter.Frame(self.main_window)
        self.bottom_frame = tkinter.Frame(self.main_window)


        # Create the widgets
        self.prompt_label = tkinter.Label(self.top_frame, text="Enter a distance in kilometers:")
        self.kilo_entry = tkinter.Entry(self.top_frame, width=10)
        self.answer_label = tkinter.Label(self.middle_frame, text="Converted to miles:")
        self.calc_button = tkinter.Button(self.bottom_frame, text="Convert", command=self.convert)

        # Pack the frames
        self.top_frame.pack(expand=True,fill="both")
        self.middle_frame.pack(expand=True,fill="both")
        self.bottom_frame.pack(expand=True,fill="both")
        
        # Pack the widgets.
        self.prompt_label.pack(side="left",padx=20)
        self.kilo_entry.pack(side="left")
        self.answer_label.pack(side="left",padx=20)
        self.calc_button.pack(side="right",padx=20)

        # Enter the tkinter main loop.
        tkinter.mainloop()

    # The convert method is a callback function for
    # the Calculate button.
    def convert(self):
        # Get the value entered by the user into the
        # kilo_entry widget.
        kilo = float(self.kilo_entry.get())

        # Convert kilometers to miles.
        miles = kilo * 0.6214

        # Convert miles to a string and create
        # the string for the new text to appear
        # on the answer label
        new_text = "Converted to miles: {mi:.2f}".format(mi=miles)
        self.answer_label.config(text=new_text)


# Create an instance of the KilometersToMilesGUI class.
kilo_conv = KilometersToMilesGUI()

Group Exercise

Create a GUI application that allows the user to type in a city and state, and then click a button which displays the population of that city. Use the zipcodes.json file from Lab 17.