Gui With Python

Overview of Python GUI development (Hello World)

Python is well suited for rapid development of cross-platform applications of all sorts, and that includes desktop GUI apps. There are choices to be made when starting to develop a GUI application in Python, however, and this article provides the information you need to set out on the right path. We will discuss what serious GUI toolkits are available for Python, their strengths and weaknesses, and provide a simple demo application for each one.

 

Demo “hello world” application overview

The demo application is simple: a window containing a combo box that presents the choices “hello”, “goodbye”, and “heyo”; a text box in which free text can be entered; and a button which, when clicked, prints a greeting assembled from the values of the combo box and text box — e.g. “Hello, world!” — to the console. Here is a mockup of the example app:

Mock hello world application for GUI development

Note that all the toolkits discussed here lend themselves to a similar object-oriented approach to our simple application; it is an object that inherits from a top-level GUI object, such as an application, window, or frame. The application window is filled with a vertical layout widget which manages the arrangement of the control widgets. Other GUI toolkits for Python, such as the long-obsolete pyFLTK or the simplistic easygui, take different approaches, but the toolkits discussed here represent the mainstream of Python GUI library development.

I have attempted to provide idiomatic code for each toolkit, but I am not expert in a couple of them; please let me know in the comments if I’ve done anything that might be misleading to new developers, and I’ll do my best to update the examples.

 

Choosing a Python GUI Toolkit

There are several toolkits available for GUI programming in Python; several are good, none are perfect, and they are not equivalent; there are situations where one or more otherwise excellent toolkits will not be appropriate. But the choice is not difficult, and for many applications, any GUI toolkit you choose will work. In the toolkit sections below, I’ve tried to honestly lay out the drawbacks and advantages of each, to help you make an informed choice.

A caution: Much of the information available online — for example, in the Python wiki’s GUI article or the Python 2.7 FAQ — is out-of-date and misleading. Many of the toolkits on those pages have been unmaintained for five years or more, and others are too immature or undocumented for serious use. Also, do not use the Choose Your GUI Toolkit page I’ve seen bandied about here and there; its weighting code makes it almost impossible to choose anything but wxPython.

We will look at the four most popular Python GUI toolkits: TkInter, wxPython, pyGTK/PyGobject, and PyQt/PySide.

TkInter

TkInter is the grand old man of the Python GUI world, having been distributed with Python almost since the language was founded. It is cross-platform and omnipresent, stable and reliable, and easy to learn, it has an object-oriented, brilliantly Pythonic API, and it works with all Python versions, but it has some drawbacks as well:

Limited support for theming

Before Python 2.7/3.1, TkInter had no support for theming, so on every platform its custom-drawn widgets looked like Motif circa 1985. Since, the ttk module has introduced themed widgets, which improve the look somewhat but leave some unorthodox controls, such as OptionMenus, in place.

Small selection of widgets

Tkinter lacks some widgets other toolkits provide, such as non-textual listboxes, real combo-boxes, scrolled windows, and others. Some additional controls have been supplied by third parties, e.g. Tix to supply the lack. Mock up your application in advance if you consider using TkInter, and make sure it can provide every control you need, or you could get burned later.

Demo App/Hello World in Tkinter

wxPython

Note that at the time of writing, wxPython is only available for Python 2.x

Guido van Rossum, the creator of Python, says of wxPython:

wxPython is the best and most mature cross-platform GUI toolkit, given a number of constraints. The only reason wxPython isn’t the standard Python GUI toolkit is that Tkinter was there first.

At least, he said that once, a long time ago; and how much GUI programming does Guido van Rossum do, anyway?

At any rate, wxPython does have a lot of good points. It has a vast set of widgets, native look-and-feel on Windows, Linux, and OS X, and a large-enough user base that at least the obvious bugs have been caught. It’s not included with Python, but installation is easy, and it’s available for all recent Python 2.x releases; wxPython is probably now the most popular GUI library for Python.

It’s not perfect, though; its documentation is atrocious, and though the exemplary demo app is priceless documentation itself, it’s about all the help you’re going to get. I personally find the API unPythonic and unpleasant, but others disagree. Still, you’ll almost never get in the middle of a project using wxPython and find it can’t do what you need, which is a big recommendation for it.

Demo App/Hello World in wxPython

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import  wx
classExampleApp(wx.Frame):
    def__init__(self):
        # Every wx app must create one App object
        # before it does anything else using wx.
        self.app=wx.App()
        # Set up the main window
        wx.Frame.__init__(self,
                          parent=None,
                          title=‘wxPython Example’,
                          size=(300,200))
        # The greetings available
        self.greetings=[‘hello’,‘goodbye’,‘heyo’]
        # Layout panel and hbox
        self.panel=wx.Panel(self,size=(300,200))
        self.box=wx.BoxSizer(wx.VERTICAL)
        # Greeting combobox
        self.greeting=wx.ComboBox(parent=self.panel,
                                    value=‘hello’,
                                    size=(280,1),
                                    choices=self.greetings)
        # Add the greeting combo to the hbox
        self.box.Add(self.greeting,0,wx.TOP)
        self.box.Add((1,10))
        # Recipient entry
        self.recipient=wx.TextCtrl(parent=self.panel,
                                     size=(280,1),
                                     value=‘world’)
        # Add the greeting combo to the hbox
        self.box.Add(self.recipient,0,wx.TOP)
        # Add padding to lower the button position
        self.box.Add((1,100))
        # The go button
        self.go_button=wx.Button(self.panel,10,‘&Go’)
        # Bind an event for the button
        self.Bind(wx.EVT_BUTTON,self.print_result,self.go_button)
        # Make the button the default action for the form
        self.go_button.SetDefault()
        # Add the button to the hbox
        self.box.Add(self.go_button,0,flag=wx.ALIGN_RIGHT|wx.BOTTOM)
        # Tell the panel to use the hbox
        self.panel.SetSizer(self.box)
    defprint_result(self,*args):
        ”’ Print a greeting constructed from
            the selections made by the user. ”’
        print(‘%s, %s!’%(self.greeting.GetValue().title(),
                           self.recipient.GetValue()))
    defrun(self):
        ”’ Run the app ”’
        self.Show()
        self.app.MainLoop()
# Instantiate and run
app=ExampleApp()
app.run()

Leave a comment