Python GUI Tkinter

Tkinter is the standard GUI library for Python.  Python when combined with Tkinter provides a fast and easy way to create GUI applications.  Tkinter provides a powerful object-oriented interface to the Tk GUI toolkit.

Creating a GUI application using Tkinter is easy. All you need to do is perform the following steps:

  • Import the Tkinter module.
  • Create the GUI application main window.
  • Add one or more of the above-mentioned widgets to the GUI application.
  • Enter the main event loop to take action against each event triggered by the user.
from tkinter import Tk
tk = Tk()

tk.mainloop()  #starts the event loop and actually show your window

A window should pop up like this one.  Nothing exciting so far, let’s keep going.

gui1

Widgets

tkinter provides various controls, such as buttons, labels and text boxes used in a GUI application. These controls are commonly called widgets.

There are currently 15 types of widgets in tkinter. We present these widgets as well as a brief description in the following table.  Read them quickly but keep moving!

Operator Description
Button The Button widget is used to display buttons in your application.
Canvas The Canvas widget is used to draw shapes, such as lines, ovals, polygons and rectangles, in your application.
Checkbutton The Checkbutton widget is used to display a number of options as checkboxes. The user can select multiple options at a time.
Entry The Entry widget is used to display a single-line text field for accepting values from a user.
Frame The Frame widget is used as a container widget to organize other widgets.
Label The Label widget is used to provide a single-line caption for other widgets. It can also contain images.
Listbox The Listbox widget is used to provide a list of options to a user.
Menubutton The Menubutton widget is used to display menus in your application.
Menu The Menu widget is used to provide various commands to a user. These commands are contained inside Menubutton.
Message The Message widget is used to display multiline text fields for accepting values from a user.
Radiobutton The Radiobutton widget is used to display a number of options as radio buttons. The user can select only one option at a time.
Scale The Scale widget is used to provide a slider widget.
Scrollbar The Scrollbar widget is used to add scrolling capability to various widgets, such as list boxes.
Text The Text widget is used to display text in multiple lines.
Toplevel The Toplevel widget is used to provide a separate window container.
Spinbox The Spinbox widget is a variant of the standard Tkinter Entry widget, which can be used to select from a fixed number of values.
PanedWindow A PanedWindow is a container widget that may contain any number of panes, arranged horizontally or vertically.
LabelFrame A labelframe is a simple container widget. Its primary purpose is to act as a spacer or container for complex window layouts.
tkMessageBox This module is used to display message boxes in your applications.

 

Button

Now we will add a button that prints a message by running a function called “hello.”

from tkinter import *

def hello():
    print("Hello gui button user!")

tk = Tk() #makes a window appear
btn = Button(tk, text="Click Me", command=hello)
btn.pack()

tk.mainloop()  #starts the event loop and actually show your window

guiButton

Add more buttons

This is going to look a little complicated at first but read it through and see if it makes sense.  There are some confusing things added in here.   Like why do we have to import “messagebox” and “*.”  “messagebox” has some special behind the scenes things that it does.  Just know it must be called by name.

“root” is just another variable name, nothing special about it other than it gets used as the first object in tkinter quite often.

There are 3 layout managers in tkinter:  “pack”, “grid” and “place”  (do mix together!)  They can be used to place items in specific location on your GUI interface.  The one below use pack.

Copy the code below and run it.  Then change things and see what you learn by playing around with it.

from tkinter import *
from tkinter import messagebox

class ButtonHolder(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.pack()  #packs the frame

        self.redbutton = Button(self, text='Red', fg='red', bg='white', command=self.onClickRed)
        self.redbutton.config(height = 1, width = 8)
        self.redbutton.pack(side = LEFT)

        self.greenbutton = Button(self, text='Green', fg='green', bg='white', command=self.onClick)
        self.greenbutton.config(height = 1, width = 8)
        self.greenbutton.pack(side = LEFT)

        self.bluebutton = Button(self, text='Blue', fg='blue', bg='white', command=self.onClick)
        self.bluebutton.config(height = 1, width = 8)
        self.bluebutton.pack(side = LEFT)

        self.blackbutton = Button(self, text='Black', fg='black', bg='white', command=self.onClickBlack)
        self.blackbutton.config(height = 1, width = 8)
        self.blackbutton.pack(side = LEFT)



    def onClick(self):
        print("Great color choice!")

    def onClickRed(self):
        messagebox.askquestion('Quick Question','You feeling OK?')
        messagebox.showinfo("Warm Thoughts", "think healthy!")

    def onClickBlack(self):
        print('You chose black')

root = Tk()
root.title('Hello, Tkinter!')
root.geometry('300x100') # Size 300 wide x 200 tall
ButtonHolder(root)
root.mainloop()

gui4Buttons

The above code may be a bit confusing to some of you.  I threw it out there to let you see what kinds of things we can do.  Everyone reading this should be able to make some modifications to the code and start playing around with it.

You can see how the different buttons call different functions.  I added a pop-up example for you as well with the Red Button.

 

Frames

Frames are like boxes that contain stuff.  When you pack a frame it is like packing a box in a garage or warehouse.  You decide if you want to pack it against the front, back, left or right wall.  The default for packing is the left and centered.

We will make four frames filled as follows:

  • frame1:  textbox, 7, 8, 9, /
  • frame2: 4, 5, 6, *
  • fame3: 1, 2, 3, –
  • frame4: 0, ., =
import sys
from tkinter import *


def clear():
    txtDisplay.delete(0,END)
    return

root = Tk()
frame = Frame(root)
frame.pack()

root.title('My Calculator')

num1=StringVar()

frame0 = Frame(root)
frame0.pack(side = TOP)
txtDisplay = Entry(frame, textvariable=num1, bd=20, insertwidth=1, font=30)
#bd is border size, insert width is the width of the insertion cursor
txtDisplay.pack(side=TOP)

button1 = Button(frame0, padx=14, pady=14, bd=8, text='Clear', fg="black", width=17, command=clear)
button1.pack(side = LEFT)
#button2 = Button(frame0, padx=14, pady=14, bd=8, text=' ', fg="black")
#button2.pack(side = LEFT)
#button3 = Button(frame0, padx=14, pady=14, bd=8, text=' ', fg="black")
#button3.pack(side = LEFT)
button4 = Button(frame0, padx=14, pady=14, bd=8, text='/', fg="black")
button4.pack(side = LEFT)

frame1 = Frame(root)
frame1.pack(side=TOP)

button5 = Button(frame1, padx=14, pady=14, bd=8, text='7', fg="black")
button5.pack(side = LEFT)
button6 = Button(frame1, padx=14, pady=14, bd=8, text='8', fg="black")
button6.pack(side = LEFT)
button7 = Button(frame1, padx=14, pady=14, bd=8, text='9', fg="black")
button7.pack(side = LEFT)
button8 = Button(frame1, padx=14, pady=14, bd=8, text='*', fg="black")
button8.pack(side = LEFT)


frame2 = Frame(root)
frame2.pack(side=TOP)

button9 = Button(frame2, padx=14, pady=14, bd=8, text='4', fg="black")
button9.pack(side = LEFT)
button10= Button(frame2, padx=14, pady=14, bd=8, text='5', fg="black")
button10.pack(side = LEFT)
button11 = Button(frame2, padx=14, pady=14, bd=8, text='6', fg="black")
button11.pack(side = LEFT)
button12 = Button(frame2, padx=14, pady=14, bd=8, text='-', fg="black")
button12.pack(side = LEFT)

frame3 = Frame(root)
frame3.pack(side=TOP)

button13 = Button(frame3, padx=14, pady=14, bd=8, text='1', fg="black")
button13.pack(side = LEFT)
button14= Button(frame3, padx=14, pady=14, bd=8, text='2', fg="black")
button14.pack(side = LEFT)
button15 = Button(frame3, padx=14, pady=14, bd=8, text='3', fg="black")
button15.pack(side = LEFT)
button16 = Button(frame3, padx=14, pady=14, bd=8, text='+', fg="black")
button16.pack(side = LEFT)

frame4 = Frame(root)
frame4.pack(side=TOP)

#button17 = Button(frame4, padx=14, pady=14, bd=8, text=' ', fg="black")
#button17.pack(side = LEFT)
button18= Button(frame4, padx=14, pady=14, bd=8, text='0', fg="black", width=9)
button18.pack(side = LEFT)
button19 = Button(frame4, padx=14, pady=14, bd=8, text='.', fg="black")
button19.pack(side = LEFT)
button20 = Button(frame4, padx=14, pady=14, bd=8, text='=', fg="black")
button20.pack(side = LEFT)

root.mainloop()

calculator

I commented out some buttons because I did not need them.  It was easier to build the layout with button there and then later I changed the size of the nearby buttons and commented out the unused ones.

None of the above buttons do anything with exception of the clear button.  If you type in the textbox and then hit clear you will see it deletes the text.

Whew!  You are doing great!