Tkinter GUI Framework: Part Three

Tkinter GUI

Creating dialog boxes in Tkinter using the Pydev module with Eclipse.

Form and function are key to creating a good GUI. In this article, we’ll go one step further and control the actual appearance of widgets.

Up to this point, we have used the default look for our widgets. This is somewhat drab, so to create programs that are visually appealing, we want to tweak the look of our widgets. For example, we can change the font and background/foreground colors.

import tkinter
from tkinter import *
root = Tk()
labelfont = ('times', 36, 'italic')

widget = Label(root, text='This is a test.')
widget.config(bg='black', fg='blue')

widget.pack(expand=YES, fill=BOTH)
root.mainloop()

Although all the program does is display a window with some text in it, the design does draw the user’s attention.

Radio Buttons and Checkboxes

In addition to windows, frame, labels and buttons, sometimes you want to use radio buttons and checkboxes to give your users more choices. Aside from appearance, radio buttons and checkboxes differ in one significant way: radio buttons offer users a list of options, but allow them to select only one; checkboxes offer users many options and lets them choose as many as they want.

For example, here’s some code that implements radio buttons:

import tkinter 
from tkinter import *
state = ''
buttons = []

def choose(i): 
	global state
	state = i
	for btn in buttons: 
		btn.deselect()
	buttons[i].select()

root = Tk()
for i in range(4):
	radio = Radiobutton(root, text=str(i), value=str(i), command=(lambda i=i: choose(i) )
	radio.pack(side=BOTTOM) 
	buttons.append(radio)

root.mainloop()
print("You chose the following number: ",state)

This program creates a series of buttons ranging from 0-3 (four in total) with the number 1, 2 and 3 highlighted by default. The user can then choose any of the buttons. Once a button is chosen, any other button’s state becomes False, meaning that the button is no longer selected. When the users close out of the program, they are given a statement showing which number they chose.

For a similar effect with checkboxes, try this code:

from tkinter import *
states = []
def check(i):
	states[i] = not states[i]

root = Tk()

for i in range(4):
	test = Checkbutton(root, text=str(i), command=(lambda i=i: check(i)) )
	test.pack(side=TOP)
	states.append(0)
root.mainloop()
print(states)

The last line in the program is print(states), which prints out the states list – the values of the check boxes. This, if you check off boxes 1 and 4, your result will be:

[True, 0, 0, True]

Dialog Boxes

Sometimes you will want to give the user a piece of additional information. You have probably seen dialog boxes in programs. They pop up whenever there is an error, or a program wants to confirm something. Tkinter offers two types of dialog boxes: modal and nonmodal. Modal dialog boxes wait for some action from the user before going away, andpause the progress of the program. Nonmodal dialog boxes do not interrupt the flow of the program.
Creating a dialog box in Tkinter is almost a trivial process. For example, we can create a simple function to generate a dialog box like so:

def dialog():
	win = Toplevel()
	Label(win, text='This is a dialog box').pack()

We need some means of invoking the dialog box from the main window, so the main program will have this code:

root = Tk()
Button(root, text='Click This', command=dialog).pack()
root.mainloop()

You will also need the usual headers at the beginning:

import sys
from tkinter import *

This will create a main window, and when you click on the button in the main window, it will launch a simple, nonmodal dialog box that has some text in it. This is OK, but we really want a dialog box that actually does something, so let’s rewrite the dialog function:

def dialog():
	win = Toplevel()
	Label(win, text='This is a dialog box').pack()
	Button(win, text='Click this button', command=win.destroy).pack()
	if makemodal:
		win.focus_set()
		win.grab_set()
		win.wait_window()

You will need to add this line before the dialog function:

makemodal = (len(sys.argv) > 1)

When the button in the main window is clicked, the program will launch a modal dialog box and that box will take the focus. When you click on the button in the dialog box, it will close itself, and the original window will take back focus.

External Links

How to Install Tkinter at unpythonic.net

Tkinter wiki at python.org

Tkinter GUI Framework: Part One

Tkinter

Tkinter in action with the PyDev module in Eclipse under Windows 8.1.

There is wide support for writing GUIs with Python with many different toolkits. These toolkits, binary modules for Python that interface with native code written in C/C++, all have different APIs and different feature sets. Only one comes with Python by default: the TK GUI toolkit.

Other options are wxPython, PyQT, and pyGTK. For this series of articles, we will be using Tkinter, which is Python’s standard GUI package and comes installed with Python. It is perhaps the most used GUI programming kit and is portable across virtually every platform.

Installing Tkinter

If you installed Python under Windows, the Python Windows installer includes Tcl/Tk as well as Tkinter. This is essentially a one-click install of everything needed. Linux and the BSD platforms require a separate installation of Tcl/Tk. This is usually available as a binary package. Under Ubuntu/Debian/Mint, you can use the following command:

sudo apt-get install python python-tk idle python-pmw python-imaging

This installs Python, Tkinter (which is not really needed since it automatically gets installed with Python), IDLE, Python MegaWidgets and PIL. In Fedora Core, it’s:

yum install tinker

Getting Started with Tkinter

The first thing to understand is that most GUI frameworks, including Tkinter, are based on a widget model. A widget is a component of a GUI. Buttons, labels and text boxes are all widgets. Most widgets have graphical representations on screen, but some widgets (such as tables and boxes) exist only to contain other widgets and arrange them on the screen. A GUI is constructed out of an arrangement of widgets.

In this script, we create a GUI of a simple window and a label:

import tkinter
from tkinter import *
widget = Label(None, text='This is my first GUI')
widget.pack()
widget.mainloop()

The first thing the script does is import the Tkinter module. Next, we could either import Label from Tkinter, for simply import all (*) from Tkinter (we did the latter). After that, we create an object for each widget (in this case, Label). The Label is then arranged in the parent window. Finally, the widget is displayed.

This is acceptable as a first GUI script, but it would be nice if the label would re-center itself when the dialog box that contains it is resized (if you try to resize it, you will see that this is not the case). However, we can fix this with a small code change:

import tkinter
from tkinter import *
Label(text='This is my first GUI').pack(expand=YES, fill=BOTH)
mainloop()

When you run the program, try resizing the window. You will see the “This is my first GUI” text label stay centered no matter what the window looks like.

In these initial examples, we created the widgets and configured them at the same time. However, we may want to wait to configure them after they are created:

import tkinter
from tkinter import *
root = Tk()

widget = Label(root)
widget.config(text='This is my first GUI')
widget.pack(side=TOP, expand=YES, fill=BOTH)
root.mainloop()

In this example, we called upon the configure method to achieve the same result as in the previous example. If we wanted to, we could change the appearance of the widget later in the program.

External Links

How to Install Tkinter at unpythonic.net

Tkinter wiki at python.org