Building interfaces - Python in easy steps (2014)

Python in easy steps (2014)

9

Building interfaces

This chapter demonstrates how to create graphical windowed applications with Python.

Launching a window

Responding to buttons

Displaying messages

Gathering entries

Listing options

Polling radio buttons

Checking boxes

Adding images

Summary

Launching a window

The standard Python module that you can use to create graphical applications is called “tkinter” - a toolkit to interface with the system GUI (Graphical User Interface).

The tkinter module can be imported into a program like any other module to provide attributes and methods for windowed apps. Every tkinter program must begin by calling the Tk() constructor to create a window object. The window’s size can, optionally, be specified as a ‘widthxheight’ string argument to the window object’s geometry() method. Similarly, the window’s title can be specified as a ‘title’ string argument to the window object’s title() method. If not specified, default size and title values will be used.

image

There can be only one call to the Tk() constructor and it must be at the start of the program code.

Every tkinter program must also call the window object’s mainloop() method to capture events, such as when the user closes the window to quit the program. This loop should appear at the end of the program as it also handles window updates that may be implemented during execution.

With tkinter, all the graphical controls that can be included in the application window, such as buttons or checkboxes, are referred to as “widgets”. Perhaps the simplest widget is a non-interactive label object that merely displays text or an image in the app interface. A label object can be created by specifying the window object’s name and text=’string’ as arguments to a Label() constructor.

Once created, each widget, such as a label, must then be added to the window using one of these “geometry manager” methods:

pack() - places the widget against a specified side of the window using TOP, BOTTOM, LEFT, or RIGHT constant values specified to its side= argument

place() - places the widget at XY coordinates in the window using numerical values specified to its x= and y= arguments

grid() - places the widget in a cell within the window using numerical values specified to its row= and column= arguments

image

The grid() geometry manager method is demonstrated in the example here.

Optionally, the pack() method may include a fill argument to expand the widget in available space. For example, with fill = ‘x’. Alternatively, the pack() method may include padx and pady arguments to expand the widget along an axis by a specified amount.

imageStart a new Python script with a statement to make the “tkinter” module GUI methods and attributes available from tkinter import *

image

tk_window.py

imageNext, add a statement to call upon a constructor to create a window object window = Tk()

imageNow, add a statement to specify a title for this window
window.title( ‘Label Example’ )

imageThen, add a statement to call upon a constructor to create a label object
label = Label( window , text = ‘Hello World!’ )

imageUse the packer to add the label to the window with both horizontal and vertical padding for positioning
label.pack( padx = 200 , pady = 50 )

imageFinally, add the mandatory statement to maintain the window by capturing events
window.mainloop()

imageSave the program in your scripts directory then open a Command Prompt window there and run this program with the command python tk_window.py - to see a window appear containing a label widget

image

image

Widgets will not appear in the window when running the program unless they have been added with a geometry manager.

Responding to buttons

A Button widget provides a graphical button in an application window that may contain either text or an image to convey the button’s purpose. A button object is created by specifying the window name and options as arguments to a Button() constructor. Each option is specified as an option=value pair. The command option must always specify the name of a function or method to call when the user clicks that button. The most popular options are listed below, together with a brief description:

Option:

Description:

activebackground

Background color when the cursor is over

activeforeground

Foreground color when the cursor is over

bd

Border width in pixels (default is 2)

bg

Background color

command

Function to call when clicked

fg

Foreground color

font

Font for button label

height

Button height in text lines, or pixels for images

highlightcolor

Border color when in focus

image

Image to be displayed instead of text

justify

Multiple text lines as LEFT, CENTER, or RIGHT

padx

Horizontal padding

pady

Vertical padding

relief

Border style of SUNKEN, RIDGE, RAISED or GROOVE

state

Enabled status of NORMAL or DISABLED

underline

Index number in text of character to underline

width

Button width in letters, or pixels for images

wraplength

Length at which to wrap text

The values assigned to other options determine the widget’s appearance. These can be altered by specifying a new option=value pair as an argument to the widget’s configure() method. Additionally, a current option value can be retrieved by specifying its name as a string argument to the widget’s cget() method.

image

You can also call a button’s invoke() method to, in turn, call the function nominated to its command option.

imageStart a new Python script by making GUI features available then create a window and specify a title
from tkinter import *

window = Tk()

window.title( ‘Button Example’ )

image

tk_button.py

imageNext, create a button to exit the program when clicked
btn_end = Button( window , text = ‘Close’ , command=exit )

imageNow, add a function to toggle the window’s background color when another button gets clicked
def tog() :

if window.cget( ‘bg’ ) == ‘yellow’ :

window.configure( bg = ‘gray’ )

else :

window.configure( bg = ‘yellow’ )

imageThen, create a button to call the function when clicked
btn_tog = Button( window , text = ‘Switch’ , command=tog )

imageAdd the buttons to the window with positional padding
btn_end.pack( padx = 150 , pady = 20 )

btn_tog.pack( padx = 150 , pady = 20 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_button.py - click the button to see the window’s background color change

image

image

Only the function name is specified to the command option. Do not add trailing parentheses in the assignment.

image

The ‘gray’ color is the original default color of the window.

Displaying messages

A program can display messages to the user by calling methods provided in the “tkinter.messagebox” module. This must be imported separately and its lengthy name can, usefully, be assigned a short alias by an import as statement.

A message box is created by supplying a box title and the message to be displayed as the two arguments to one of these methods:

Method:

Icon:

Buttons:

showinfo()

image

OK

showwarning()

image

OK

showerror()

image

OK

askquestion()

image

Yes (returns the string ‘yes’) and No (returns the string ‘no’)

askokcancel()

image

OK (returns 1) and Cancel

askyesno()

image

Yes (returns 1) and No

askretrycancel()

image

Retry (returns 1) and Cancel

Those methods that produce a message box containing a single OK button return no value when the button gets clicked by the user. Those that do return a value can be used to perform conditional branching by testing that value.

image

Only the askquestion() method returns two values - the askyesno() No button and both Cancel buttons return nothing.

imageStart a new Python program by making GUI features available and messagebox features available as a short alias
from tkinter import *
import tkinter.messagebox as box

image

tk_message.py

imageNext, create a window object and specify a title
window = Tk()

window.title( ‘Message Box Example’ )

imageAdd a function to display various message boxes
def dialog() :

var = box.askyesno( ‘Message Box’ , ‘Proceed?’ )

if var == 1 :

box.showinfo( ‘Yes Box’, ‘Proceeding...’ )

else :

box.showwarning( ‘No Box’, ‘Cancelling...’ )

imageThen, create a button to call the function when clicked
btn = Button( window , text = ‘Click’ , command=dialog )

imageAdd the button to the window with positional padding
btn.pack( padx = 150 , pady = 50 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_message.py - click the button to see the message boxes appear

image

image

Options can be added as a third argument to these method calls. For example, add type=’abortretryignore’ to get three buttons.

Gathering entries

An Entry widget provides a single-line input field in an application where the program can gather entries from the user. An entry object is created by specifying the name of its parent container, such as a window or frame name, and options as arguments to an Entry() constructor. Each option is specified as an option=value pair. Popular options are listed below together with a brief description:

Option:

Description:

bd

Border width in pixels (default is 2)

bg

Background color

fg

Foreground color used to render the text

font

Font for the text

highlightcolor

Border color when in focus

selectbackground

Background color of selected text

selectforeground

Foreground color of selected text

show

Hide password characters with show=’*’

state

Enabled status of NORMAL or DISABLED

width

Entry width in letters

Multiple widgets can be grouped in frames for better positioning. A frame object is created by specifying the name of the window to a Frame() constructor. The frame’s name can then be specified as the first argument to the widget constructors to identify it as that widget’s container.

image

Use the Text widget instead of an Entry widget if you want to allow the user to enter multiple lines of text.

When actually adding widgets to the frame you can specify which side to pack them to in the frame with TOP, BOTTOM, LEFT, or RIGHT constants. For example, entry.pack( side=LEFT ).

Typically, an entry widget will appear alongside a label describing the type of input expected there from the user, or alongside a button widget that the user can click to perform some action on the data they have entered, so positioning in a frame is ideal.

Data currently entered into an entry widget can be retrieved by the program using that widget’s get() method.

imageStart a new Python program by making GUI features available and messagebox features available as a short alias
from tkinter import *

import tkinter.messagebox as box

image

tk_entry.py

imageNext, create a window object and specify a title
window = Tk()

window.title( ‘Entry Example’ )

imageNow, create a frame to contain an entry field for input
frame = Frame( window )

entry = Entry( frame )

imageThen, add a function to display data currently entered
def dialog() :

box.showinfo( ‘Greetings’ , ‘Welcome ’ + entry.get() )

imageNow, create a button to call the function when clicked
btn = Button( frame, text = ‘Enter Name’ , command=dialog )

imageAdd the button and entry to the frame at set sides
btn.pack( side = RIGHT , padx = 5 )

entry.pack( side = LEFT )

frame.pack( padx = 20 , pady = 20 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_entry.py - enter your name and click the button to see a greeting message appear

image

image

image

Use a Label widget instead of an Entry widget if you want to display text that the user cannot edit.

Listing options

A Listbox widget provides a list of items in an application from which the user can make a selection. A listbox object is created by specifying the name of its parent container, such as a window or frame name, and options as arguments to a Listbox() constructor. Popular options are listed below, together with a brief description:

Option:

Description:

bd

Border width in pixels (default is 2)

bg

Background color

fg

Foreground color used to render the text

font

Font for the text

height

Number of lines in list (default is 10)

selectbackground

Background color of selected text

selectmode

SINGLE (the default) or MULTIPLE selections

width

Listbox width in letters (default is 20)

yscrollcommand

Attach to a vertical scrollbar

image

With Tkinter, a scrollbar is a separate widget that can be attached to Listbox, Text, Canvas and Entry widgets.

Items are added to the listbox by specifying a list index number and the item string as arguments to its insert() method.

You can retrieve any item from a listbox by specifying its index number within the parentheses of its get() method. Usefully, a listbox also has a curselection() method that returns the index number of the currently-selected item, so this can be supplied as the argument to its get() method to retrieve the current selection.

imageStart a new Python program by making GUI features available and messagebox features available as a short alias
from tkinter import *

import tkinter.messagebox as box

image

tk_listbox.py

imageNext, create a window object and specify a title
window = Tk()

window.title( ‘Listbox Example’ )

imageNow, create a frame to contain widgets
frame = Frame( window )

imageCreate a listbox widget offering three list items
listbox = Listbox( frame )

listbox.insert( 1 , ‘HTML5 in easy steps’ )
listbox.insert( 2 , ‘CSS3 in easy steps’ )
listbox.insert( 3 , ‘JavaScript in easy steps’ )

imageNext, add a function to display a listbox selection
def dialog() :

box.showinfo( ‘Selection’ , ‘Your Choice: ’ + \

listbox.get( listbox.curselection() ) )

imageNow, create a button to call the function when clicked
btn = Button( frame , text = ‘Choose’ , command = dialog )

imageThen, add the button and listbox to the frame at set sides
btn.pack( side = RIGHT , padx = 5 )

listbox.pack( side = LEFT )

frame.pack( padx = 30 , pady = 30 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_listbox.py - select an option and click the button to see your selection confirmed

image

image

If the selectmode is set to MULTIPLE the curselection() method returns a tuple of the selected index numbers.

Polling radio buttons

A Radiobutton widget provides a single item in an application that the user may select. Where a number of radio buttons are grouped together, the user may only select any one item in the group. With tkinter, radio button objects are grouped together when they nominate the same control variable object to assign a value to upon selection. An empty string variable object can be created for this purpose using the StringVar() constructor or an empty integer variable object using the IntVar() constructor.

image

You cannot use a regular variable to store values assigned from a radio button selection - it must be an object.

A radio button object is created by specifying four arguments to a Radiobutton() constructor:

Name of the parent container, such as the frame name

Text for a display label, specified as a text=text pair

Control variable object, specified as a variable=variable pair

Value to be assigned, specified as a value=value pair

Each radio button object has a select() method that can be used to specify a default selection in a group of radio buttons when the program starts. A string value assigned by selecting a radio button can be retrieved from a string variable object by its get() method.

imageStart a new Python program by making GUI features available and messagebox features available as a short alias
from tkinter import *
import tkinter.messagebox as box

image

tk_radio.py

imageNext, create a window object and specify a title
window = Tk()

window.title( ‘Radio Button Example’ )

imageNow, create a frame to contain widgets
frame = Frame( window )

imageThen, construct a string variable object to store a selection
book = StringVar()

imageNext, create three radio button widgets whose value will be assigned to the string variable upon selection
radio_1 = Radiobutton( frame , text = ‘HTML5’ , \

variable = book , value = ‘HTML5 in easy steps’ )

radio_2 = Radiobutton( frame , text = ‘CSS3’ , \

variable = book , value = ‘CSS3 in easy steps’ )

radio_3 = Radiobutton( frame , text = ‘JS’ , \

variable = book , value = ‘JavaScript in easy steps’ )

imageNow, add a statement to specify which radio button will be selected by default when the program starts
radio_1.select()

imageThen, add a function to display a radio button selection and a button to call this function
def dialog() :

box.showinfo( ‘Selection’ , \

‘Your Choice: \n’ + book.get() )

btn = Button( frame , text = ‘Choose’ , command = dialog )

imageAdd the push button and radio buttons to the frame
btn.pack( side = RIGHT , padx = 5 )

radio_1.pack( side = LEFT )
radio_2.pack( side = LEFT )
radio_3.pack( side = LEFT )
frame.pack( padx = 30 , pady = 30 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_radio.py - choose an option and click the button to see your choice confirmed

image

image

A Radiobutton object has a deselect() method that can be used to cancel a selection programatically.

Checking boxes

A Checkbutton widget provides a single item in an application that the user may select. Where a number of check buttons appear together the user may select one or more items. Check button objects nominate an individual control variable object to assign a value to whether checked or unchecked. An empty string variable object can be created for this using the StringVar() constructor or an empty integer variable object using the IntVar() constructor.

A check button object is created by specifying five arguments to a Checkbutton() constructor:

Name of the parent container, such as the frame name

Text for a display label, as a text=text pair

Control variable object, as a variable=variable pair

Value to assign if checked, as an onvalue=value pair

Value to assign if unchecked, as an offvalue=value pair

An integer value assigned by a check button can be retrieved from a integer variable object by its get() method.

imageStart a new Python program by making GUI features available and messagebox features available as a short alias
from tkinter import *

import tkinter.messagebox as box

image

tk_check.py

imageNext, create a window object and specify a title
window = Tk()

window.title( ‘Check Button Example’ )

imageNow, create a frame to contain widgets
frame = Frame( window )

imageThen, construct three integer variable objects to store values

var_1 = IntVar()

var_2 = IntVar()

var_3 = IntVar()

imageCreate three check button widgets whose values will be assigned to the integer variable whether checked or not

book_1 = Checkbutton( frame , text = ‘HTML5’ , \

variable = var_1 , onvalue = 1 , offvalue = 0 )

book_2 = Checkbutton( frame , text = ‘CSS3’ , \

variable = var_2 , onvalue = 1 , offvalue = 0 )

book_3 = Checkbutton( frame , text = ‘JS’ , \

variable = var_3 , onvalue = 1 , offvalue = 0 )

imageNext, add a function to display a check button selection
def dialog() :

str = ‘Your Choice:’

if var_1.get() == 1 : str += ‘\nHTML5 in easy steps’

if var_2.get() == 1 : str += ‘\nCSS3 in easy steps’

if var_3.get() == 1 : str += ‘\nJavaScript in easy steps’

box.showinfo( ‘Selection’ , str )

imageNow, create a button to call the function when clicked
btn = Button( frame , text = ‘Choose’ , command = dialog )

imageThen, add the push button and check buttons to the frame

btn.pack( side = RIGHT , padx = 5 )

book_1.pack( side = LEFT )
book_2.pack( side = LEFT )
book_3.pack( side = LEFT )
frame.pack( padx = 30, pady = 30 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_check.py - check boxes and click the button to see your selection confirmed

image

image

A Checkbutton object has select() and deselect() methods that can be used to turn the state on or off. For example, check_1. select().

image

The state of any Checkbutton object can be reversed by calling its toggle() method.

Adding images

With the tkinter module, images in GIF or PGM/PPM file formats can be displayed on Label, Button, Text and Canvas widgets using the PhotoImage() constructor to create image objects. This simply requires a single file= argument to specify the image file. Interestingly, it also has a subsample()method that can scale down a specified image by stating a sample value to x= and y= arguments. For example, values of x=2, y=2 samples every second pixel - so the image object is half-size of the original.

image

The PhotoImage class also has a zoom() method that will double the image size with the same x=2,y=2 values.

Once an image object has been created, it can be added to a Label or Button constructor statement by an image= option.

Text objects have an image_create() method with which to embed an image into the text field. This requires two arguments to specify location and image=. For example, ‘1.0’ specifies the first line and first character.

Canvas objects have a create_image() method that requires two arguments to specify location and image=. Here, the location sets the x,y coordinates on the canvas at which to paint the image.

imageStart a new Python program by making GUI methods and attributes available then create a window object and specify a title
from tkinter import *

window = Tk()

window.title( ‘Image Example’ )

image

tk_image.py

imageNow, create an image object from a local image file
img = PhotoImage( file = ‘python.gif’ )

image

python.gif (200 × 200)

imageThen, create a label object to display the image above a colored background
label = Label( window , image = img , bg = ‘yellow’ )

imageCreate a half-size image object from the first image object
small_img = PhotoImage.subsample( img , x = 2 , y = 2 )

imageNow, create a button to display the small image
btn = Button( window , image = small_img )

imageCreate a text field and embed the small image then insert some text after it

txt = Text( window , width = 25 , height = 7 )

txt.image_create( ‘1.0’ , image = small_img )

txt.insert( ‘1.1’, ‘Python Fun!’ )

imageCreate a canvas and paint the small image above a colored background then paint a diagonal line over the top of it
can = \

Canvas( window , width = 100 , height = 100 , bg = ‘cyan’ )
can.create_image( ( 50 , 50 ), image = small_img )
can.create_line( 0 , 0 , 100 , 100, width = 25 , fill = ‘yellow’ )

imageThen, add the widgets to the window
label.pack( side = TOP )

btn.pack( side = LEFT , padx = 10 )

txt.pack( side = LEFT )

can.pack( side = LEFT, padx = 10 )

imageFinally, add the loop to capture this window’s events
window.mainloop()

imageSave the file in your scripts directory then open a Command Prompt window there and run this program with the command python tk_photo.py - to see the image

image

image

Notice that the Text method is image_create() but the Canvas method is create_image() - similar yet different.

image

Text and Canvas widgets are both powerful and flexible - discover more online at docs.python.org/3.3/library/tkinter.html

Summary

The tkinter module can be imported into a Python program to provide attributes and methods for windowed applications

Every tkinter program must begin by calling Tk() to create a window and call its mainloop() method to capture events

The window object’s title is specified by its title() method

A label widget is created by specifying the name of its parent container and its text as arguments to the Label() constructor

Widgets can be added to an application using the pack(), grid() or place() geometry managers

A button widget is created by specifying the name of its parent container, its text, and the name of a function to call when the user pushes it, as arguments to the Button() constructor

The tkinter.messagebox module can be imported into a Python program to provide attributes and methods for message boxes

Message boxes that ask the user to make a choice return a value to the program for conditional branching

The Frame() constructor creates a container in which multiple widgets can be grouped for better positioning

The Entry() constructor creates a single line text field whose current contents can be retrieved by its get() method

Items are added to a Listbox object by its insert() method and retrieved by specifying their index number to its get() method

Radiobutton and Checkbutton objects store values in the StringVar or IntVar object nominated by their variable attribute

The PhotoImage() constructor creates an image object that has a subsample() method which can scale down the image

Images can be added to Button and Label objects, embedded in Text objects, and painted on Canvas objects