GUI

Python has a few options for creating GUIs (Graphical User Interfaces). We will learn Tkinter because it is part of the standard library and easy to use.

GUIs are a type of user interface that allows users to run your program using viusal indicators like buttons, text boxes, and scroll bars. If you are creating a program that will be run by a casual user, a GUI is a good option.

Tkinter provides a python interface to the Tk GUI toolkit. Tk is a cross platform library that allows creating of native desktop GUI elements.

Tkinter is a module, so to start, we will have to import it

import Tkinter

In [ ]:
import tkinter

Creating the main window

You will want to create the applications main window that the action will take place in. To do this, you create a Tk object

root = Tkinter.Tk()

In [ ]:
root = Tkinter.Tk()

That didn't do much, did it. To actually create the window you have to run the mainloop function on your main window

root.mainloop()

This creates the window and starts listening for actions that the user takes. This is an infinite loop, and is one of the cases where an infinite loop is actually useful (don't worry, clicking the close button on the window will break out for the loop).


In [ ]:
root.mainloop()

Deleting the main window

To quit a Tkinter application, you run the destroy method on the main window

root.destroy()

This won't do anything until you are broken out of the main loop, but it will cleanup after that happens.


In [ ]:
root.destroy()

TRY IT

Create a tkinter app main window and store it in the variable top run the mainloop function on it.


In [ ]:

Widgets

So far our GUI has been pretty boring. To make it useful we have to add "widgets" to it. Widgets are things like buttons, textboxes, labels, etc. Anything you would expect to have in a desktop application.

You need to create the widget after creating the main window, but before running mainloop

You will also need to let Tkinter know how to layout your widgets. Right now we will just use the pack method with no arguments.

widget.pack()

Button

You can create a button that when pressed will run a function. To do that you run the Button function. It takes the parent window as the first parameter, and then a list of key value params as options for look and feel, text, and command - the function that will run when the button is pushed. It returns a reference to the widget.

my_button = Tkinter.Button(window, text='my text', callback=myfunction)

In [ ]:
# A basic button
root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Button(root, text='Hello')
w.pack()

# Run the gui
root.mainloop()

In [ ]:
# a button with a callback
def my_callback():
    print("Here i am")

root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Button(root, text='Hello', command=my_callback)
w.pack()

# Run the gui
root.mainloop()

Label

A Label provides a space for the GUI programmer to place text on the screen

l = Tkinter.Label(mainwindow, text='label text')

In [ ]:
# A basic label
root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Label(root, text='Hello')
w.pack()


# Run the gui
root.mainloop()

If you want to be able to update the text in a label, you will need to use a StringVar for the text, and instead of using text keyword param, you will use textvaribale keyword parameter.

var = Tkinter.StringVar()
l = Label(root, texvariable=var)
l.pack()

var.set('New text')

In [ ]:
# A changeable label
root = Tkinter.Tk()
# Widgets go here
v = Tkinter.StringVar()
w = Tkinter.Label(root, textvariable=v)
w.pack()
v.set('Aaaah')


# Run the gui
root.mainloop()

Entry

An entry accepts a single text line from a user.

w = Entry(root)

To get the data from an entry, you can use the get method

w = Entry(root)
text = w.get()

In [ ]:
# A basic entry
root = Tkinter.Tk()
e = Tkinter.Entry(root)
e.pack()
root.mainloop()

In [ ]:
# An entry where we get the text entered.
def what_entered():
    print(e.get())

root = Tkinter.Tk()

e = Tkinter.Entry(root)
e.pack()

# Click to button to see what teh text entered is
b = Tkinter.Button(root, text='Say What?', command=what_entered)
b.pack()

root.mainloop()

TRY IT

Create a GUI that has a Label that says "What is your name?" and an entry to enter it. If you are feeling confident, add a button that will print out the name to the screen when pressed.


In [ ]:

There are many other types of widgets including canvas for drawing images and shapes, menubutton for creating menus, radio and lists for making selection, and lots of other. Look to the documentation for more info: https://docs.python.org/2/library/tkinter.html

Event driven programming

GUI programming uses a different model of programming than we are used to. In the past our program has run from top to bottom and the only way to change the outputs was to change the inputs (or use random...)

In GUIs we use event driven programming where we create our application and then listen for events like a user clicking a button or entering some data. When an event is created, then the callback function associated with that event runs. Then the next event causes a callback to run. This all happens in an infinite loop (mainloop) which is broken by you either calling destroy or close in your code in response to an event or by clicking the close button for the window.

In Event driven programming, the user determines the workflow. It will take some time to get used to thinking in these terms.

TRY IT

Give yourself a few minutes to think about event driven programming and how it is different than the previous programs you have written.


In [ ]:

Attributes

In the keyword arguments all widgets can take some attribute parameters. These can determine the widget's dimensions, colors, fonts, image, etc.

Size

  • height - height of element
  • width - width of element

In [ ]:
# A basic button
root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Button(root, text='Hello', width=50, height=1)
w.pack()

# Run the gui
root.mainloop()

Color

  • fg - foreground color of widget
  • bg - background color of widget

Color can be in hex: "#ff0000" or in words "red", "green", "blue". Hex is preferred.


In [ ]:
# A basic button
root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Button(root, text='Hello', fg="red", bg="#00aaff")
w.pack()

# Run the gui
root.mainloop()

TRY IT

Create a really, really big label that screams 'AAAAAAHHHHHHH!'


In [ ]:

Geometry

You can organize your widgets using geometry management. So far we have been using the pack method with no arguments. But you can have arguments, or use grid to create a table or place to put them in specific positions.

Pack

Pack can take some parameters

  • expand - True/False, widget should fill all space in widget's parent
  • side - which side to pack the widget against (TOP, BOTTOM, LEFT, RIGHT)
  • fill - should widget fill extra space

In [ ]:
# A basic button
root = Tkinter.Tk()
# Widgets go here
w = Tkinter.Button(root, text='Hello')
w.pack(side=Tkinter.LEFT)

# Run the gui
root.mainloop()

Grid

You can lay out your widgets in a table like fashion using grid.

  • column - column to put widget in
  • row - row to put widget in
  • columnspan - how many columns a widget occupies (default 1)
  • rowspan - how many rows a widget occupies (default 1)

In [ ]:
# A basic button
root = Tkinter.Tk()
# Widgets go here
for i in range(3):
    for j in range(4):
        text = "{}-{}".format(i, j)
        w = Tkinter.Button(root, text=text)
        w.grid(row = i, column = j)

# Run the gui
root.mainloop()

TRY IT

Create two labels "enter" on the left and "exit" on the right


In [ ]:

Project: BMI Calculator

You will create a gui that calculates BMI. The formula is

(weight/ height^2) x 703

with weight in pounds and height in inches.

  1. Create your tkinter main window.
  2. Create a label "Height (inches)" and next to that an Entry and store the entry is a variable called height
  3. Create a label "Weight (pounds)" and next to that an Entry and store the entry is a variable called weight
  4. Create a button with the text 'Calculate BMI'
  5. Create a label that uses a StringVar that doesn't say anything yet, but will be used to print the BMI later.
  6. Create a callback function called calculate that converts the data from the height and weight entries to numbers and then calculates BMI. Finally, it should set the string var to "BMI: " + bmi

In [ ]: