Genotrance

Icon

Random thoughts, ideas and experiences

wxPython Widgets – Part I

I’m currently working on AppSnap, a Windows application which simplifies software installation. It originally started out as a console application but has since graduated into being GUI based as well. More on it when it gets released in a few days. For now, I’d like to spend some time talking about a few wxPython widgets that I use in AppSnap. wxPython has some decent documentation but it is still hard to figure out all aspects of a widget for a beginner. So here’s a few common widgets and their usage. I’ve also linked to the relevant pages in the wxPython API where appropriate so as to make further investigations easier.

Note that some of the examples below have been created to fit into the context of this post. AppSnap is laid out quite differently and I’ll go over that in a separate post.

Application Icon

I’m using Py2Exe to package my Python program into a Windows application. In order to associate an icon with my executable, I do the following in my Py2Exe setup file:-

setup (
console = [{
“script” : “appsnap.py”,
“icon_resources” : [(1, “appsnap.ico”)]
}],
windows = [{
“script” : “appsnapgui.py”,
“icon_resources” : [(1, “appsnap.ico”)]
}],
options = {
“py2exe”: {
“packages” : [“encodings”],
“optimize” : 2
}
},
data_files = [(
“” , [“appsnap.ico”,”db.ini”,”config.ini”,]
)],
zipfile = “shared.lib”

)

I have a console as well as a GUI application. Both are associated with an icon file (lines in RED) so that the generated executable displays this icon when viewed in Windows Explorer. Also, note the line in BLUE. The icon is also being stored in the application package. This is to allow for the next step.

More details about icons in Py2Exe can be found here.

Window Icon

So our application executable shows up nicely with an icon in Windows Explorer. How about showing this icon in the title bar of our GUI application? The following lines show how this can be done:-

# Create icon object from file
icon = wx.Icon(name=‘appsnap.ico’, type=wx.BITMAP_TYPE_ICO)

# Associate icon with top level frame
frame.SetIcon(icon)

We create an icon object from the file bundled in the previous step and associate it with our top level frame using the SetIcon() method. Pretty simple.

Dropdown box

On AppSnap, I use a dropdown box to list the available categories of applications such as Internet, Utilities and so forth. On selecting a specific category, only applications belonging to that category are listed on the GUI.

Dropdown boxes in wxPython are implemented using the wx.Choice widget. This wasn’t too obvious initially and I had to hunt it down. Creating a dropdown is trivial:-

# Create a dropdown on an existing panel widget
dropdown = wx.Choice(parent=panel, pos=(10,10))

Now, we can add some entries into the dropdown:-

# Add a list of items to the dropdown
list = [‘All’, ‘Internet’‘Utilities’]
dropdown.AppendItems(strings=list)

Now that our dropdown has something in it, a default item can be selected:-

# Select a default item
dropdown.Select(n=0)

Next, we bind a method to the dropdown. This method will get executed every time an item is selected:-

# Bind method to dropdown
wx.EVT_CHOICE(frame, dropdown.GetId(), self.OnChoice)

We can now perform some action in our OnChoice() method:-

# Get the choice and perform some action
def OnChoice(self, event):
choice = event.GetString()
print choice

Checklist

Checklists are essentially a combination of checkboxes and a listbox. A listbox can have multiple items. On clicking an item, the listbox action is executed and on checking an item, the checkbox action is executed. Hence, two different things can be done with each item.

In AppSnap, I use a checklist box to list all the applications for the category specified in the dropdown box. On selecting or checking an application, I show its details. Once the install or uninstall button is clicked, I perform that action on each checked application.

So let’s create a checklist box:-

# Create a checklistbox on an existing panel widget
checklist = wx.CheckListBox(parent=panel, pos=(5, 40))

Let’s add some items to it:-

# Add items to listbox at the beginning
list = [‘FileZilla’, ‘Firefox’, ‘Putty’, ‘SevenZip’]
checklist.InsertItems(items=list, pos=0)

We can bind two methods, one for the selection event and one for a check event:-

# Bind method to selection
wx.EVT_LISTBOX(frame, checklist.GetId(), self.OnSelection)

# Bind method to check
wx.EVT_CHECKLISTBOX(frame, checklist.GetId(), self.OnCheck)

In AppSnap, both events do the same thing, i.e. display the application details. However, they obtain the application name differently since GetString() doesn’t seem to work for the check event:-

# Selection event – get string directly
def OnSelection(self, event):
name = event.GetString()
print name

# Check event – get ID then get string
def OnCheck(self, event):
id = event.GetSelection()
name = checklist.GetString(id)
print name

Remember the dropdown box above? The OnChoice() event is supposed to clear the checklist and populate it with the appropriate category of applications. Let’s modify the original OnChoice() event with something more functional. The method is simplified here but can be expanded as needed:-

# Get the choice and perform some action
def OnChoice(self, event):
choice = event.GetString()

# Figure out updated list based on choice
if choice == ‘Internet’:
list = [‘FileZilla’, ‘Firefox’, ‘Putty’]
elif choice == ‘Utilities’:
list = [‘SevenZip’]
else:
list = [‘FileZilla’, ‘Firefox’, ‘Putty’, ‘SevenZip’]


# Clear checklist and repopulate with new list
checklist.Clear()
checklist.InsertItems(items=list, pos=0)

AppSnap will install or uninstall all checked applications once the corresponding button is pressed. Below is a peek at how the GetChecked() method gets the list of checked items for the checklist:-

# Get all checked applications in the checklist box
def GetChecked(self):
checked = []
for i in range(checklist.GetCount()):

if checklist.IsChecked(i):
checked.append(checklist.GetString(i))

return checked

Still to Come

That’s it for now. Please let me know if this approach is helpful. Meanwhile, I’ll be working on a post that goes over the following widgets:-

Advertisements

Filed under: Programming

3 Responses

  1. Frank says:

    Small typo, It should say:

    checked.append(checklist.GetString(i))

  2. genosha says:

    Good catch! I’ve made the change.

  3. Maurits says:

    Thanks for the tips! I always use slightly different code when binding events to controls:

    (in some window, eg. frame)
    self.Bind(wx.EVT_CHOICE, self.OnChoice, dropdown)

    This takes away the need to work with clumsy IDs.

    Good luck with your program!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Twitter Updates

%d bloggers like this: