Helping ordinary people create extraordinary websites!
HOME TUTORIALS SCRIPTS WEB HOSTING BLOG FORUM
Get Our Newsletter
Email:

Python 201 - (Slightly) Advanced Python Topics

By Dave Kuhlman
2005-07-06


GUI Applications

Introduction

This section will help you to put a GUI (graphical user interface) in your Python program.

We will use a particular GUI library: PyGTK. We've chosen this because it is reasonably light-weight and our goal is to embed light-weight GUI interfaces in an (possibly) existing application.

For simpler GUI needs, consider EasyGUI, which is also described below.

For more heavy-weight GUI needs (for example, complete GUI applications), you may want to explore WxPython. See the WxPython home page at: http://www.wxpython.org/

PyGtk

Information about PyGTK is at:

A simple message dialog box

In this section we explain how to pop up a simple dialog box from your Python application.

To do this, do the following:

  1. Import gtk into your Python module.

  2. Define the dialog and its behavior.

  3. Create an instance of the dialog.

  4. Run the event loop.

Here is a sample that displays a message box:

#!/usr/bin/env python


import sys
import getopt
import gtk

class MessageBox(gtk.Dialog):
def __init__(self, message="", buttons=(), pixmap=None,
modal= gtk.TRUE):
gtk.Dialog.__init__(self)
self.connect("destroy", self.quit)
self.connect("delete_event", self.quit)
if modal:
self.set_modal(gtk.TRUE)
hbox = gtk.HBox(spacing=5)
hbox.set_border_width(5)
self.vbox.pack_start(hbox)
hbox.show()
if pixmap:
self.realize()
pixmap = Pixmap(self, pixmap)
hbox.pack_start(pixmap, expand=gtk.FALSE)
pixmap.show()
label = gtk.Label(message)
hbox.pack_start(label)
label.show()
for text in buttons:
b = gtk.Button(text)
b.set_flags(gtk.CAN_DEFAULT)
b.set_data("user_data", text)
b.connect("clicked", self.click)
self.action_area.pack_start(b)
b.show()
self.ret = None
def quit(self, *args):
self.hide()
self.destroy()
gtk.mainquit()
def click(self, button):
self.ret = button.get_data("user_data")
self.quit()

# create a message box, and return which button was pressed
def message_box(title="Message Box", message="", buttons=(), pixmap=None,
modal= gtk.TRUE):
win = MessageBox(message, buttons, pixmap=pixmap, modal=modal)
win.set_title(title)
win.show()
gtk.mainloop()
return win.ret

def test():
result = message_box(title='Test #1',
message='Here is your message',
buttons=('Ok', 'Cancel'))
print 'result:', result

USAGE_TEXT = """
Usage:
python simple_dialog.py [options]
Options:
-h, --help Display this help message.
Example:
python simple_dialog.py
"""

def usage():
print USAGE_TEXT
sys.exit(-1)

def main():
args = sys.argv[1:]
try:
opts, args = getopt.getopt(args, 'h', ['help'])
except:
usage()
relink = 1
for opt, val in opts:
if opt in ('-h', '--help'):
usage()
if len(args) != 0:
usage()
test()

if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')

Some explanation:

  • First, we import gtk

  • Next we define a class MessageBox that implements a message box. Here are a few important things to know about that class:

    • It is a subclass of gtk.Dialog.

    • It creates a label and packs it into the dialog's client area. Note that a Dialog is a Window that contains a vbox at the top of and an action_area at the bottom of its client area. The intension is for us to pack miscellaneous widgets into the vbox and to put buttons such as "Ok", "Cancel", etc into the action_area.

    • It creates one button for each button label passed to its constructor. The buttons are all connected to the click method.

    • The click method saves the value of the user_data for the button that was clicked. In our example, this value will be either "Ok" or "Cancel".

  • And, we define a function (message_box) that (1) creates an instance of the MessageBox class, (2) sets its title, (3) shows it, (4) starts its event loop so that it can get and process events from the user, and (5) returns the result to the caller (in this case "Ok" or "Cancel").

  • Our testing function (test) calls function message_box and prints the result.

  • This looks like quite a bit of code, until you notice that the class MessageBox and the function message_box could be put it a utility module and reused.

A simple text input dialog box

And, here is an example that displays an text input dialog:

#!/usr/bin/env python


import sys
import getopt
import gtk

class EntryDialog( gtk.Dialog):
def __init__(self, message="", default_text='', modal= gtk.TRUE):
gtk.Dialog.__init__(self)
self.connect("destroy", self.quit)
self.connect("delete_event", self.quit)
if modal:
self.set_modal(gtk.TRUE)
box = gtk.VBox(spacing=10)
box.set_border_width(10)
self.vbox.pack_start(box)
box.show()
if message:
label = gtk.Label(message)
box.pack_start(label)
label.show()
self.entry = gtk.Entry()
self.entry.set_text(default_text)
box.pack_start(self.entry)
self.entry.show()
self.entry.grab_focus()
button = gtk.Button("OK")
button.connect("clicked", self.click)
button.set_flags(gtk.CAN_DEFAULT)
self.action_area.pack_start(button)
button.show()
button.grab_default()
button = gtk.Button("Cancel")
button.connect("clicked", self.quit)
button.set_flags(gtk.CAN_DEFAULT)
self.action_area.pack_start(button)
button.show()
self.ret = None
def quit(self, w=None, event=None):
self.hide()
self.destroy()
gtk.mainquit()
def click(self, button):
self.ret = self.entry.get_text()
self.quit()

def input_box(title="Input Box", message="", default_text='',
modal= gtk.TRUE):
win = EntryDialog(message, default_text, modal=modal)
win.set_title(title)
win.show()
gtk.mainloop()
return win.ret

def test():
result = input_box(title='Test #2',
message='Enter a valuexxx:',
default_text='a default value')
if result is None:
print 'Canceled'
else:
print 'result: "%s"' % result

USAGE_TEXT = """
Usage:
python simple_dialog.py [options]
Options:
-h, --help Display this help message.
Example:
python simple_dialog.py
"""

def usage():
print USAGE_TEXT
sys.exit(-1)

def main():
args = sys.argv[1:]
try:
opts, args = getopt.getopt(args, 'h', ['help'])
except:
usage()
relink = 1
for opt, val in opts:
if opt in ('-h', '--help'):
usage()
if len(args) != 0:
usage()
test()

if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')

Most of the explanation for the message box example is relevant to this example, too. Here are some differences:

  • Our EntryDialog class constructor creates instance of gtk.Entry, sets its default value, and packs it into the client area.

  • The constructor also automatically creates two buttons: "OK" and "Cancel". The "OK" button is connect to the click method, which saves the value of the entry field. The "Cancel" button is connect to the quit method, which does not save the value.

  • And, if class EntryDialog and function input_box look usable and useful, add them to your utility gui module.

A file selection dialog box

This example shows a file selection dialog box:

#!/usr/bin/env python


import sys
import getopt
import gtk

class FileChooser(gtk.FileSelection):
def __init__(self, modal=gtk.TRUE, multiple=gtk.TRUE):
gtk.FileSelection.__init__(self)
self.multiple = multiple
self.connect("destroy", self.quit)
self.connect("delete_event", self.quit)
if modal:
self.set_modal(gtk.TRUE)
self.cancel_button.connect('clicked', self.quit)
self.ok_button.connect('clicked', self.ok_cb)
if multiple:
self.set_select_multiple(gtk.TRUE)
## self.hide_fileop_buttons()
self.ret = None
def quit(self, *args):
self.hide()
self.destroy()
gtk.mainquit()
def ok_cb(self, b):
if self.multiple:
self.ret = self.get_selections()
else:
self.ret = self.get_filename()
self.quit()

def file_sel_box(title="Browse", modal=gtk.FALSE, multiple=gtk.TRUE):
win = FileChooser(modal=modal, multiple=multiple)
win.set_title(title)
win.show()
gtk.mainloop()
return win.ret

def file_open_box(modal=gtk.TRUE):
return file_sel_box("Open", modal=modal, multiple=gtk.TRUE)
def file_save_box(modal=gtk.TRUE):
return file_sel_box("Save As", modal=modal, multiple=gtk.FALSE)

def test():
result = file_open_box()
print 'open result:', result
result = file_save_box()
print 'save result:', result

USAGE_TEXT = """
Usage:
python simple_dialog.py [options]
Options:
-h, --help Display this help message.
Example:
python simple_dialog.py
"""

def usage():
print USAGE_TEXT
sys.exit(-1)

def main():
args = sys.argv[1:]
try:
opts, args = getopt.getopt(args, 'h', ['help'])
except:
usage()
relink = 1
for opt, val in opts:
if opt in ('-h', '--help'):
usage()
if len(args) != 0:
usage()
test()

if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')

A little guidance:

  • There is a pre-defined file selection dialog. We sub-class it.

  • This example displays the file selection dialog twice: once with a title "Open" and once with a title "Save As".

  • Note how we can control whether the dialog allows multiple file selections. And, if we select the multiple selection mode, then we use get_selections instead of get_filename in order to get the selected file names.

  • The dialog contains buttons that enable the user to (1) create a new folder, (2) delete a file, and (3) rename a file. If you do not want the user to perform these operations, then call hide_fileop_buttons. This call is commented out in our sample code.

Note that there are also predefined dialogs for font selection (FontSelectionDialog) and color selection (ColorSelectionDialog)

EasyGUI

If your GUI needs are minimalist and your application is imperative rather than event driven, then you may want to consider EasyGUI. As the name suggests, it is extremely easy to use.

How to know when you might be able to use EasyGUI:

  • You do not need menus.

  • Your GUI needs amount to little more than displaying a dialog now and then to get responses from the user.

  • You do not want to write an event driven application, than is one in which your code sits and waits for the the user to initiate operation, for example, with menu items.

EasyGUI is available at http://www.ferg.org/easygui/.

Information about EasyGUI is provided in a text file in the distribution.

EasyGUI provides functions for a variety of commonly needed dialog boxes, including:

  • A message box displays a message.

  • A yes/no message box displays "Yes" and "No" buttons.

  • A continue/cancel message box displays "Continue" and "Cancel" buttons.

  • A choice box displays a selection list.

  • An enter box allows entry of a line of text.

  • An integer box allows entry of an interger.

  • A multiple entry box allows entry into multiple fields.

  • Code and text boxes support the display of text in monospaced or porportional fonts.

  • File and directory boxes enable the user to select a file or a directory.

A simple EasyGUI example

Here is a simple example that prompts the user for an entry, then shows the response in a message box:

def testeasygui():

response = easygui.enterbox(message='Enter your name:',
title='Name Entry')
easygui.msgbox(message=response,
title='Your Response',
)


Tutorial Pages:
» Regular Expressions
» Unit Tests
» Extending and embedding Python
» Parsing
» GUI Applications
» Guidance on Packages and Modules


Copyright (c) 2003 Dave Kuhlman


 | Bookmark
Related Tutorials:
» Python and Java - A Side by Side Comparison
» Learn Python in 10 Minutes
» Python 101 - Introduction to Python
» Google Sitemaps
» Python 101
» Python vs. Perl