Graphical Toolkits for OS X: wxPython
Pages: 1, 2
Let's go through this sample code line by line to make sure we understand what is happening here. First, we tell the computer where the Python interpreter is located on the shebang line, the first line of the program. Your pythonw binary might live in another place, but that is unlikely unless you've moved it yourself. The second line is a Python directive telling Python to import the
wx module, which is the wxPython GUI code. The third line instantiates a new app from the wxPython module called wx.PySimpleApp.
The fourth line instantiates a frame, which is really the "window," and passes three arguments to this object. Note if you change the text "Hello World," you will see your changed text in the title bar of the window when you rerun the simple program. The fifth line shows the frame by calling Show like this:
frame.Show(True), and the last line fires up the entire program by saying "run the main loop" with
Now let's actually do something with our program to make it a little more than just a toy. For this article we are going to build a small application that searches your Apache log file to see how many Firefox and Safari browsers have come to your web site. It is a cursory program, just designed to show how to create dialogs and buttons and to bind those buttons to events. If you were writing a real application, you would include error checking and lots of other things that we have not included here.
Our program, called browsers.py, begins with the familiar shebang line and imports the
wx classes from the
wx module. We declare our variables and open our log file on line 11. Line 12 begins iterating over the file and the
if control says if we find a string like "Firefox" then we increment our variable, and we do this with the string "Safari" as well. From this little Python snippet we get our values, then we incorporate these on line 19, and one line later, we close the file.
#!/usr/bin/env pythonw import wx # global variables need to be declared here foxes = 0 saf = 0 # your apache log file may be located somewhere else fil = open('/var/log/httpd/access_log', 'r') for line in fil: if 'Firefox' in line: foxes = foxes+1 elif 'Safari' in line: saf = saf+1 # message contains the result of the above code message = " we have %d Firefox and %d Safari browsers." % (foxes, saf) fil.close() # begin wx code class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) # our central button b = wx.Button(self, -1, "Click to search log file") # bind the button to an action, in this case OnClick b.Bind(wx.EVT_BUTTON, self.OnClick) Sizer = wx.BoxSizer(wx.VERTICAL) # by adding a stretchable spacer above and below we center the button Sizer.Add((1,1), 1) # this adds a one by one pixel spacer # but the "1" means that it has a stretch factor of 1 Sizer.Add(b, 0, wx.ALIGN_CENTER) # the "0" means it won't stretch Sizer.Add((1,1), 2) # try changing the stretch factors, and see what you get. self.SetSizer(Sizer) def OnClick(self, event): msgdialog = wx.MessageDialog(self,message,style=wx.OK) msgdialog.ShowModal() class MyFrame(wx.Frame): def __init__(self, parent=None, id=-1, title='Apache log file search', pos=wx.DefaultPosition, size=(200, 200)): wx.Frame.__init__(self, parent, id, title, pos, size) panel = MyPanel(self) class App(wx.App): def OnInit(self): frame = MyFrame() frame.Center() frame.Show() self.SetTopWindow(frame) return True def main(): app = App() app.MainLoop() if __name__ == '__main__': main()
Line 23 begins our use of the
wx module. First we start by creating a panel appropriately named MyPanel, and the class definition is done on the following lines. On line 28 we have our button defined with the text string "Click to search log file" as the button's text. We then bind this button on the next line to the code defined as
"self.OnClick". This is important, since it means that now when someone clicks on the button, code bound to "OnClick" gets run. In our case this begins on line 43, below
"def OnClick", and it essentially creates a message dialog and shows that dialog.
Figure 2. The results dialog box
We skipped over some code with comments that helps position our windows and frames and creates space within them. Most of the code and comments come from a program in the wxPythonDemo zip file, which contains lots of excellent sample code to help you get started.
Finally the rest of the code in our program does Python magic that involves inheriting class objects and bringing those objects to life via object calls. You can read more about classes on Python's web site, python.org, as well as on the wxPython site. As you progress and start to feel the need to take greater advantage of the framework and packaging that Apple provides, you will want to read more at Apple's ADC site as well (click on the link that says "Software Delivery Guide"). You may also want to take a look at the wxPython by Example (Manning Publications).
I hope you enjoyed this article. Stay tuned as we check out Qt and GTK+!
Jeremiah Foster fell in love with the Mac years ago. One day, when his new computer had an application called "Terminal," his life was changed. Some years and UNIX certification later, he is still in love with his Mac.
Return to Mac DevCenter.