Dialogs in wxPython

You are probably already familiar with a few dialogs that can be used in your wxPython applications. Of course, wxPython contains many more dialogs, ranging in complexity from very simple to pretty advanced and covering a variety of topics, from text selection to color selection. In this article, we’ll take a look at more of wxPython‘s dialogs – what they are for and how they are placed in an application.

wxSingleChoiceDialog

Instead of using a wxListBox to gather input from a user, you can use the wxSingleChoiceDialog. Upon calling it, a dialog is displayed to the user with a list of items that the user can select. The user may only select one item on the list. At the bottom of the dialog, there is an “OK” button and a “Cancel” button. Let’s create a simple application with the dialog:

from wxPython.wx import *

from wxPython.lib.dialogs import *

application = wxPySimpleApp()

# Create a list of choices

choices = [ 'Red', 'Blue', 'Green', 'Pink', 'White' ]

# Create the dialog

dialog = wxSingleChoiceDialog ( None, ‘Pick something….’, ‘Dialog Title’, choices )

# Show the dialog

dialog.ShowModal()

# Destroy the dialog

dialog.Destroy()

Of course, to make our dialog of any use, we’ll have to catch the user’s selection and perhaps react to the user pressing the “Cancel” button:

from wxPython.wx import *

application = wxPySimpleApp()

choices = [ 'Red', 'Blue', 'Green', 'Pink', 'White' ]

dialog = wxSingleChoiceDialog ( None, ‘Pick something….’, ‘Dialog Title’, choices )

# The user pressed the “OK” button in the dialog

if dialog.ShowModal() == wxID_OK:

   print ‘Position of selection:’, dialog.GetSelection()

   print ‘Selection:’, dialog.GetStringSelection()

# The user exited the dialog without pressing the “OK” button

else:

   print ‘You did not select anything.’

dialog.Destroy()

If we want to give the user the option of selecting multiple items by pressing the shift key while clicking a selection or holding down the mouse and moving the cursor down, we can do so with wxMultiChoiceDialog:

from wxPython.wx import *

application = wxPySimpleApp()

choices = [ 'Red', 'Blue', 'Green', 'Pink', 'White' ]

dialog = wxMultiChoiceDialog ( None, ‘Pick something….’, ‘Dialog Title’, choices )

# The user pressed the “OK” button in the dialog

if dialog.ShowModal() == wxID_OK:

   selected = dialog.GetSelections()

   for selection in selected:

      print str ( selection ) + ‘: ‘ + choices [ selection ]

# The user exited the dialog without pressing the “OK” button

else:

   print ‘You did not select anything.’

dialog.Destroy()

{mospagebreak title=wxScrolledMessageDialog}

Suppose you need to display a long message, such as the terms of use for your application. A good way to display this would be to use a wxScrolledMessageDialog. It features a read-only multi-line text box, and it’s very easy to put into your applications:

from wxPython.wx import *

application = wxPySimpleApp()

# Set up the text

text = “”"Once upon a time, there lived a knight named Sir Esthimus.

Sir Esthimus decided to marry the princess one day. So, he went to the king

and asked if he could marry his lovely daughter. The king said that he had to

defeat the strongest goblin in the kingdom’s dungeons. The knight agreed to

fight the goblin, and the next day, the king summoned both the beast and the

knight to the town square. A sturdy iron fence had been erected overnight to

keep the two fighters inside. The king waved his hand — the signal for the match

to begin. The knight pulled out his sword, and goblin pulled out his spear. The goblin

then pierced the knight’s sword arm, so the knight lost the fight and did not get to marry

the princess.

Notice the scrollbar to the right. It enables you to

write

large

amounts

of

text

to

the

dialog and have it organized neatly.”"”

# Create the dialog

dialog = wxScrolledMessageDialog ( self, text, ‘Fairy Tale’ )

# Show the dialog

dialog.ShowModal()

{mospagebreak title=wxProgressDialog}

Any time you are required to do large amounts of work in your application, it is a good idea to let the user know your application’s progress in the process. A wxProgressDialog will do the job nicely. Let’s emulate an application that takes a long time:

import time

for x in xrange ( 25 ):

   # Spend some time doing nothing

   time.sleep ( 2 )

When running it, I have no idea how much progress has been made. This is easily fixed. Let’s make a wxProgressDialog and update it after each cycle in the loop:

from wxPython.wx import *

application = wxPySimpleApp()

# Create a dialog to show progress

dialog = wxProgressDialog ( ‘Progress’, ‘Doing nothing in a large amount of time.’, maximum = 25 )

for x in xrange ( 25 ):

   # Spend some time doing nothing

   # We’ll use wxSleep rather than time.sleep

   wxSleep ( 2 )

   # Update our progress and change the message

   dialog.Update ( x + 1, ‘On step ‘ + str ( x + 1 ) + ‘.’ )

Our dialog makes things a lot better. I’m sure you’re wondering what the maximum argument is for. Basically, it sets the maximum number that can be set in Update. Once that maximum is hit, the dialog’s progress bar will be complete. It’s very simple. Because we call the sleep method 25 times, I made maximum match that. You can set maximum to whatever you wish. The default is 100.

Notice that as soon as our task is complete, the dialog is hidden from us. This is because of the wxPD_AUTO_HIDE style, which is applied by default. It hides the dialog once maximum is reached. We can change this by manually setting the style:

from wxPython.wx import *

application = wxPySimpleApp()

dialog = wxProgressDialog ( ‘Progress’, ‘Doing nothing in a large amount of time.’, maximum = 25, style = wxPD_APP_MODAL )

for x in xrange ( 25 ):

   wxSleep ( 2 )

   dialog.Update ( x + 1, ‘On step ‘ + str ( x + 1 ) + ‘.’ )

If we want to improve our progress dialog even more, we can do so by applying the wxPD_ELAPSED_TIME style, which shows the total amount of time that has gone by since the start of the process:

from wxPython.wx import *

application = wxPySimpleApp()

dialog = wxProgressDialog ( ‘Progress’, ‘Doing nothing in a large amount of time.’, maximum = 5, style = wxPD_APP_MODAL | wxPD_ELAPSED_TIME)

for x in xrange ( 5 ):

   wxSleep ( 2 )

   dialog.Update ( x + 1, ‘On step ‘ + str ( x + 1 ) + ‘.’ )

To accompany the wxPD_ELAPSED_TIME style, we can apply the wxPD_ESTIMATED_TIME style. It shows the total time that wxPython thinks the process will take:

from wxPython.wx import *

application = wxPySimpleApp()

dialog = wxProgressDialog ( ‘Progress’, ‘Doing nothing in a large amount of time.’, maximum = 5, style = wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME )

for x in xrange ( 5 ):

   wxSleep ( 2 )

   dialog.Update ( x + 1, ‘On step ‘ + str ( x + 1 ) + ‘.’ )

Alternatively, we can pass wxPD_REMAINING_TIME. It displays the time wxPython believes is left until the process is finished:

from wxPython.wx import *

application = wxPySimpleApp()

dialog = wxProgressDialog ( ‘Progress’, ‘Doing nothing in a large amount of time.’, maximum = 5, style = wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME )

for x in xrange ( 5 ):

   wxSleep ( 2 )

   dialog.Update ( x + 1, ‘On step ‘ + str ( x + 1 ) + ‘.’ )

{mospagebreak title=ImageDialog}

The ImageDialog is a very nice dialog. It displays the images in a given directory. It’s very simple to use:

from wxPython.wx import *

# Import the required module

from wxPython.lib import imagebrowser

application = wxPySimpleApp()

# Create the dialog

dialog = imagebrowser.ImageDialog ( None )

# Show the dialog

dialog.ShowModal()

# Destroy the dialog

dialog.Destroy()

Of course, we’ll need to retrieve the file name of the image that the user specifies. This is easily done:

from wxPython.wx import *

from wxPython.lib import imagebrowser

application = wxPySimpleApp()

dialog = imagebrowser.ImageDialog ( None )

# Display the file name if the user selected one

if dialog.ShowModal() == wxID_OK:

   print ‘You picked:’, dialog.GetFile()

# Otherwise, yell and scream at the user for cancelling

else:

   print ‘You did not select an image!’

dialog.Destroy()

If we need to set a directory other than the current directory, it’s possible to do so by passing a second argument:

from wxPython.wx import *

from wxPython.lib import imagebrowser

application = wxPySimpleApp()

# Specify a directory

dialog = imagebrowser.ImageDialog ( None, ‘C:’ )

if dialog.ShowModal() == wxID_OK:

   print ‘You picked:’, dialog.GetFile()

else:

   print ‘You did not select an image!’

dialog.Destroy()

{mospagebreak title=wxDirDialog}

If your application requires the user to select a directory for something, consider using wxDirDialog. It allows the user to pick a directory from a tree:

from wxPython.wx import *

application = wxPySimpleApp()

# Create the dialog

dialog = wxDirDialog ( None, message = ‘Pick a directory.’ )

# Show the dialog and get user input

if dialog.ShowModal() == wxID_OK:

   print ‘Directory:’, dialog.GetPath()

# The user cancelled

else:

   print ‘No directory.’

# Get rid of the dialog

dialog.Destroy()

It is also possible to allow the user to create a new directory from within the dialog by passing the wxDD_NEW_DIR_BUTTON style:

from wxPython.wx import *

application = wxPySimpleApp()

dialog = wxDirDialog ( None, message = ‘Pick a directory.’, style = wxDD_NEW_DIR_BUTTON )

if dialog.ShowModal() == wxID_OK:

   print ‘Directory:’, dialog.GetPath()

else:

   print ‘No directory.’

dialog.Destroy()

{mospagebreak title=wxFileDialog}

The last dialog we are going to examine in this article is the wxFileDialog. It allows the user to save or open a file. Setting up a basic dialog is pretty simple. Let’s set up one that allows the user to select a file to open:

from wxPython.wx import *

application = wxPySimpleApp()

# Create an open file dialog

dialog = wxFileDialog ( None, style = wxOPEN )

# Show the dialog and get user input

if dialog.ShowModal() == wxID_OK:

   print ‘Selected:’, dialog.GetPath()

# The user did not select anything

else:

   print ‘Nothing was selected.’

# Destroy the dialog

dialog.Destroy()

Let’s make our dialog more complicated. First, let’s create some filters so the user can select a file type from a list. Second, let’s display a message on the dialog. Third, let’s allow multiple files to be selected:

from wxPython.wx import *

application = wxPySimpleApp()

# Create a list of filters

# This should be fairly simple to follow, so no explanation is necessary

filters = ‘All files (*.*)|*.*|Text files (*.txt)|*.txt’

dialog = wxFileDialog ( None, message = ‘Open something….’, wildcard = filters, style = wxOPEN | wxMULTIPLE )

if dialog.ShowModal() == wxID_OK:

   # We’ll have to make room for multiple files here

   selected = dialog.GetPaths()

   for selection in selected:

      print ‘Selected:’, selection

else:

   print ‘Nothing was selected.’

dialog.Destroy()

Now let’s create a dialog that allows us to save files. This is done by simply changing the style wxOPEN to wxSAVE:

from wxPython.wx import *

application = wxPySimpleApp()

# Create a save file dialog

dialog = wxFileDialog ( None, style = wxSAVE )

# Show the dialog and get user input

if dialog.ShowModal() == wxID_OK:

   print ‘Selected:’, dialog.GetPath()

# The user did not select anything

else:

   print ‘Nothing was selected.’

# Destroy the dialog

dialog.Destroy()

A lot of applications present the user with a confirmation dialog if he or she selects a file that already exists. This can be accomplished in your own application by using wxOVERWRITE_PROMPT:

from wxPython.wx import *

application = wxPySimpleApp()

# Create a save file dialog

dialog = wxFileDialog ( None, style = wxSAVE | wxOVERWRITE_PROMPT )

# Show the dialog and get user input

if dialog.ShowModal() == wxID_OK:

   print ‘Selected:’, dialog.GetPath()

# The user did not select anything

else:

   print ‘Nothing was selected.’

# Destroy the dialog

dialog.Destroy()

Conclusion

We’ve looked at a variety of dialogs that wxPython provides. Dialogs allow programmers to implement common features in their applications without doing much work at all. Instead of working with complex controls to do a simple task, a programmer can call a few methods and have it all done for him or her. All dialogs are simple to create and manage, as this article has thrown through examples. They are worth using in many wxPython applications – both large and small.

Google+ Comments

Google+ Comments