Python GUI using Tkinter

We will use assignments 1.5.2 and 1.5.3 from mypltw.org.

Source files for 1.5.2
(See the Tkinter_tutorial file for some examples on creating widgets in an app)

Source files for 1.5.3

Tkinter Guide on effbot.org
Tkinter Resources on python.org
Other Tkinter Resources elsewhere on python.org
TheNewBoston – TkInter Videos

Here’s a VERY basic Tkinter app that’s just a blank window:

from tkinter import *
root = Tk()
root.mainloop()

Notes on this blank app:

  • Notice how the import command is different than usual. Doing it this was lets us do “Tk()” instead of “Tkinter.Tk()” in line 2.
  • root is an object that represents the entire app itself.
  • mainloop() is a function of the app that starts the app and keeps it responding to user input. It contains things like while loops that constantly check for user input and keep the visual indicators updated. It abstracts a bunch of work behind the scenes, such as refreshing the screen, so the programmer doesn’t have to think about it.
  • Don’t create more than one Tk() object. Don’t run the mainloop() function more than once.

Buttons Example

This example creates two buttons called b1 and b2.

Each button calls its grid() function to place itself into the app in a certain location.

A Label is just a piece of text. Label objects can either keep the same text all the time (use text attribute: text=”your_text_here”) or it can be connected to a StringVar object (use textvariable attribute: textvariable=”your_StringVar_name”).

In this case we want the Label’s text to change in response to a button, so we use a StringVar that we call labeltext to store the text we want displayed in the Label. This object has a set() function that can change its text.

A StringVar is a Tkinter object that not only stores string data but also knows how to interact with other Tkinter objects.

Using a plain string variable as the textvariable will not work properly.

The buttons have a command attribute. This is the name of a function that will be called every time the button is clicked. In this case, our functions are called b1_clicked and b2_clicked. These functions call the set() function of the labeltext StringVar object, which changes what text is displayed in our Label.

Notice that the button click functions don’t actually change anything about the Label object itself (L1). Changing the StringVar will automatically cause the Label to be updated.

from tkinter import *

def b1_clicked():
    L1['text'] = 'You clicked the first button.'

def b2_clicked():
    L1['text'] = 'OH NO, YOU CLICKED THE SECOND BUTTON.'
    
root = Tk()

b1 = Button(root, text="Click for info",command=b1_clicked)
b1.pack()

b2 = Button(root, text="Click for info",command=b2_clicked)
b2.pack()

L1 = Label(root, text='No buttons pushed yet')
L1.pack()

root.mainloop()

Slider Example

This example creates two Scale objects, which are sliding number scale widgets. Each of these scales is connected to an IntVar object, which is short for ‘integer variable.’

Whenever the scale is adjusted by the user, the IntVar’s value becomes equal to the new scale position.

To get the currently selected value from the scale, use the IntVar’s get() function.

The IntVar’s are called value1 and value2, and you can see the value1.get() and value2.get()( functions in the code below. These each evaluate out to an integer which can be used in a math expression.

The display_info function is called constantly as the app runs. This function gets the current values of the IntVar objects, multiplies them and updates the StringVar object. This automatically causes the Label’s text to be updated with the new multiplication product.

Notice that the Scale objects both have a command attribute defined: command=display_info.

Notice that display_info is defined as display_info(root) instead of just display_info(). We didn’t have to include the ‘root’ parameter for the button click functions (previous example), but sliders require this parameter. If this isn’t included, the scale’s command function will not work.

from Tkinter import *

def display_info(root):
    labeltext.set('Product of the numbers is ' + str( value1.get()*value2.get() ))

root = Tk()

value1 = IntVar()
s1 = Scale(root, from_=1, to=10, label='Value', variable=value1, command=display_info)
s1.grid(row=0, column=0)

value2 = IntVar()
s2 = Scale(root, from_=1, to=10, label='Value', variable=value2, command=display_info)
s2.grid(row=1, column=0)

labeltext = StringVar()
labeltext.set('Info will be displayed here.')
L1 = Label(root, textvariable=labeltext)
L1.grid(row=2, column=0)

root.mainloop()