Graphical Python Apps in Minutes

Tutorials – TkInter

Article from Issue 199/2017
Author(s):

Expand your Python knowledge and write GUI apps with a smattering of code, thanks to the TkInter toolkit.

We Linux Voicers have, over the years, argued for more consistency on the Linux desktop. We appreciate that choice and diversity is good, and there are reasons why the Gtk and Qt graphical toolkits exist. Indeed, competition between them can be a good thing. But the downside to this – especially if you're running a mixture of Gtk and Qt apps on your desktop – is inconsistency in the user experience. It's not a big deal in the grand scheme of things, and apps using different toolkits can still get along nicely, but sometimes you notice some rough edges.

With this in mind, we'd normally be reticent to bring another toolkit into the mix (see the "Other Toolkit Options" box). But that's what we're going to do in this tutorial, with TkInter. This lets you create graphical applications in Python – providing you with buttons, menus, text entry boxes, and other widgets. But, why are we devoting these pages to TkInter, when Python interfaces to Gtk and Qt already exist?

Other Toolkit Options

As we mentioned, TkInter is just one option for creating graphical apps in Python. It has the benefit of being readily available on pretty much every operating system that runs Python, but it's not the most feature-rich toolkit. If you want to write more advanced apps, there are some options worth considering (although you'll have to pore through quite a bit of documentation).

PyQt [1] is one of the best-known Python toolkits and is available for Python 2 and Python 3. It's a well-maintained project with extensive documentation, and a commercial version with extra features and support options is available as well.

If you're more of a Gtk/Gnome fan, then check out PyGObject [2]. This module gives you access to oodles of Gnome features and functions and has become the successor project to the now-dormant PyGtk.

Then there's Kivy [3] for developing multi-touch apps that can run on iOS and Android, and many more. The Python wiki has a detailed list of toolkits [4], showing which platforms they run on, and the most recent update (so you can quickly tell if a toolkit is being actively developed or may be suffering from bitrot).

Well, TkInter has some significant advantages. First, it's Python's de facto GUI toolkit and is usually installed by default alongside the language. Whereas PyQt and PyGtk can be quite fiddly to install – especially on other platforms like Windows and Mac OS – TkInter is always there. You can write cross-platform apps and only require your end users to install Python. Second, it's quite easy to use. If you have a command-line Python script and want to add a graphical layer on top of it, TkInter lets you do this with relatively few lines of code.

TkInter isn't the prettiest toolkit, nor is it absolutely loaded with features. But it's well worth learning for the reasons mentioned above, so we'll show you how to get started with it and work with the various widgets it provides. Whether you're a Python guru or just getting started with the language, you'll learn some valuable skills for the future. In the immortal words of Mario, let's-a go!

TkInter Basics

Many distros install TkInter alongside Python by default, but you may need to install it separately. If you see an error message when running the following code, search your package manager for python3-tk or python3-tkinter and install that package.

Here's our first TkInter program – save this code into a plain text file called test.py (Listing 1) and run it in Python 3 (e.g., python3 test.py).

Listing 1

test.py

01 from tkinter import *
02
03 root_win = Tk()
04
05 my_label = Label(root_win, text = "Hello, world!")
06 my_label.pack()
07
08 root_win.mainloop()

Let's go through this step by step. On the first line, we tell Python to import the TkInter module, and specifically all of the methods and features that it provides. (If you're quite new to Python, you don't need to be concerned with the specifics here – just think of this line as making TkInter available to the rest of your program).

On the next line, we create our first widget. In TkInter, as indeed with most toolkits, widgets are simply GUI elements – buttons, checkboxes, sliders, text entry boxes, and so forth. Even windows are widgets. So, on this line of code, we tell TkInter to create a new "root" window widget, which we call root_win. The root window is like the root directory in your Linux installation – it's the base of everything else. So, we need to create a root window before we can do anything else.

Now, a root window on its own isn't much use, so let's add something to it: a text label. This is a non-interactive widget that simply displays some text inside the window. To achieve this, we use the Label() method from TkInter with two parameters: the window in which it should be placed, and the text to be displayed. You can see in our program that we chose to place the label inside root_win and use "Hello, world!" as the text.

So far so good – but now we need to tell TkInter to fit or "pack" our newly created label inside the root window. That's what we do with my_label.pack() – we don't need any other parameters here. Finally, we start TkInter's main loop, which displays all of the widgets we've created and processes events relating to them. Because our program isn't interactive, the main loop doesn't do much here – it simply shows the window (like in Figure 1) and waits for the user to close it (via the window manager).

Figure 1: Our first program -- it doesn't do much, but it shows that TkInter is installed and working correctly.

Adding Buttons and Callbacks

Let's now make an interactive program with some additional features (Listing 2). In the previous example, the window was given a generic title ("tk") and automatically sized to fit the label we created. However, we have control of these things, so let's customize them and add a button to perform an action.

Listing 2

Additional Features

01 from tkinter import *
02
03 def do_click():
04     print("Clicked")
05
06 root_win = Tk()
07 root_win.title("LV MegaApp 1.0")
08 root_win.geometry(200x100)
09
10 my_button = Button(root_win, text = "Click me", command = do_click)
11 my_button.pack()
12
13 root_win.mainloop()

In this program, we import TkInter like we did previously, but then we define a function called do_click. All this does is print a "Clicked" message in the terminal, but later in the code we're going to connect this function with a button. In other words, when the user clicks a button, "Clicked" is displayed in the terminal window.

After the function, we set up a root window as usual – but this time we perform two extra operations on it. First of all, we give the window a custom title, and then we set the window's size in pixels: 200 wide by 100 high. Note that the user can still resize the window using his/her window manager, but we've provided its default dimensions.

Next up, we use TkInter's aptly named "Button" method to create a clickable button. This takes three parameters: the window in which it should be placed, the text that is displayed on the button, and the command that should be executed when the button is clicked. In our case, we tell TkInter to run the do_click() function we created earlier.

Finally, we pack that button into the root window and start the main loop – handing control over to TkInter. Et voila, you'll see a window like in Figure 2. Try clicking the button a few times, and watch the output in the terminal where you launched your program. This is still a very simple app, but we now know how to make programs interactive. Not bad for just a few lines of code!

Figure 2: Now we're going interactive! Clicking the button generates text in the terminal from which the app was launched.

A Complete Program

You can do quite a bit with buttons alone, especially if your TkInter app is just a front end to a command-line script, but there are many other widgets you can incorporate into your programs as well. For the next program, we'll create a graphical tool for calculating the area of a circle based on its radius (using pi). For this, we'll need a text entry box in which the user can type the radius, along with a button to trigger the calculation. Then we'll need a text label that's updated with the newly calculated area. As an extra bonus, we'll throw in a menu as well.

Listing 3 shows the code – have a look and see if you can work out what's going on. Then, we'll examine it in detail.

Listing 3

Create a Graphical Tool

01 import math, sys
02 from tkinter import *
03 from tkinter import messagebox
04
05 def about_dialog():
06     messagebox.showinfo("About", "Version 1.0")
07
08 def exit_app():
09     sys.exit(0)
10
11 def calc_area(*args):
12     area_result = (float(radius.get()) ** 2) * math.pi
13     area.set(round(area_result, 2))
14
15 root_win = Tk()
16 root_win.title("Area calculator")
17 root_win.geometry("200x100")
18
19 main_menu = Menu(root_win)
20 root_win.config(menu = main_menu)
21 file_menu = Menu(main_menu)
22 main_menu.add_cascade(label="File", menu = file_menu)
23 file_menu.add_command(label="About", command = about_dialog)
24 file_menu.add_command(label="Exit", command = exit_app)
25
26 radius = StringVar()
27 radius.set("0")
28 area = StringVar()
29
30 area_label = Label(root_win, text = "Area:").grid(column = 1, row = 1)
31
32 area_value = Label(root_win, textvariable = area).grid(column = 2, row = 1)
33
34 radius_label = Label(root_win, text = "Radius:").grid(column = 1, row = 2)
35
36 radius_entry = Entry(root_win, width = 7, textvariable = radius).grid(column = 2, row = 2)
37
38 calc_button = Button(root_win, text="Calculate", command = calc_area).grid(column = 2, row = 3)
39
40 root_win.mainloop()

Some parts of this will be familiar to you, but we've introduced a bunch of new things as well. Along with the TkInter module, we also import the sys and math modules as we'll need them later. Next, we define a couple of functions that will be linked to menu items. The first one, about_dialog, simply pops up a TkInter message box with two parameters: the box title, and the text to be displayed. Note that in the second parameter, you can include newline (\n) characters if you want to display a larger amount of text.

Our second function, exit_app, will be called when the user clicks Exit in the menu. This simply calls the exit function in Python's sys module with a return code of zero – that is, the program exited correctly. Following this, we have a third function that does the work of calculating the area of a circle based on its radius; we'll come back to this in a moment.

Then, the main code begins: We create a root window with a title and default horizontal and vertical size, as we did previously. Next, we create a main menu and attach it to the root window – but by default it's blank. To add a specific menu, like File, we have to incorporate it into the main menu, and then we can add individual menu items. This is exactly what we do in the last two lines of this code block: We create About and Exit items under the File menu, connecting them to the two functions we defined early in the program.

Next, we have a chunk of code beginning with this: radius = StringVar(). Essentially, we need to use two variables in our program, one for the radius (which the user can modify) and one for the area (which is calculated from the radius). Now, we could use vanilla Python variables for this, but we'd stumble across a problem: When the variables change, like when the user enters a new radius, the program won't update automatically. TkInter doesn't track these variables and update the display accordingly.

Therefore, we need to use TkInter's own StringVar routine to create special string variables that can be used in widgets – and those widgets are updated on the screen when the values in them change. So, we create a TkInter string variable called radius, setting it to zero, and another called area.

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Python’s Tkinter Library

    Use Tkinter to control your Rasp Pi projects from a smartphone or tablet.

  • Practical Python in Linux

    We’ll introduce you to Python, an easy-to-learn scripting language, and also help you get started creating your own practical Python scripts.

  • Pi FM Radio

    Low-cost RTL-SDR dongles can read frequencies between 24 and 1,766MHz. We built a simple FM radio with a Raspberry Pi, a USB dongle based on the RTL2832U chipset, an LCD HAT, and some Python code.

  • Workspace: EasyGUI

    If you need to add graphical elements to Python script, EasyGUI can help beginners and experts alike.

  • Plasmoids

    With KDE 4.4, plasmoids can now be written in JavaScript or QtScript, thus opening up a whole new class of applications. Marcel shows how easy it is to build JavaScript plasmoids.

comments powered by Disqus

Direct Download

Read full article as PDF:

News