Extending the bareminimum wxPython program

We showed you a bare-minimum wxPython program to give you a comfortable start, but something that small isn't useful for anything but discussion. By oversimplifying the code, we produced a Python program that was easy to understand, but difficult to extend—which is not how we would encourage you to create serious wxPython programs.

So now we're going to enhance this minimal program until it has a reasonable amount of functionality, incorporates common Python programming standards, and can serve as a proper foundation for your own programs. Listing 1.2 shows the next iteration, which we named spare.py.

Listing 1.2 The spare version of our minimal program.

Spare.py is a starting point for a wxPython program C

import wx o class Frame(wx.Frame): pass class App(wx.App):

def OnInit(self):

self.frame = Frame(parent=None, title='Spare') self.frame.Show()

self.SetTopWindow(self.frame) f o return True if __name__ == '__ma app = App() app.MainLoop()

This version is still quite small, only 14 lines of code, but we added several important items that get us closer to what we would consider good, solid code.

O The first line in the file is now a shebang line. It looks like a Python comment, which it is, but on some operating systems, such as Linux and Unix, the shebang tells the operating system how to find the interpreter that will execute the program file. If this program file was then given executable privileges (using the chmod command, for example) we could run the program from the operating system command line by simply supplying the program name:

% spare.py

The shebang line is a convenience for Unix and Mac OS X users and is simply ignored on other platforms. Even if you aren't using one of those systems, it's polite to include it on a script that might be executed cross-platform.

C We added a module docstring (documentation string). When the first statement in a module is a string, that string becomes the docstring for the module and is stored in the module's_doc_ attribute. You can access the docstring in your code, some development environments, and even the Python interpreter running in interactive mode:

Spare.py is a starting point for simple wxPython programs. >>>

Docstrings are but one example of Python's powerful introspection capabilities, and we will encourage you to provide them for modules, classes, methods, functions, and any other place that Python supports. Python development tools, such as PyCrust, are able to use the docstring to provide useful information to a developer while you are coding. d We changed the way we created the frame object. The "bare" version of this program simply created an instance of the wx.Frame class. In the "spare" version we defined our own Frame class as a subclass of wx.Frame. At this point it hasn't made any difference to the final results, but you'll want your own Frame class if you want anything interesting, such as text, buttons, and menus, to appear in your frame. Introducing your own custom Frame class now sets the stage for future iterations. In fact, once your Frame class becomes complicated, you'll probably want to move it into its own module and import it into your main program. O We added a reference to the frame instance as an attribute of the application class instance. Again, we're setting the stage for things to come, as well as demonstrating how easy it is to add attributes to Python classes. It makes no difference that the attribute is a reference to a complex, graphical object, such as a frame. To Python, an object is an object is an object. © Inside the OnInit() method we called the App class's own SetTopWindow() method, passing it our newly created frame instance. We didn't have to define the SetTopWindow() method because it was inherited from the wx.App parent class. It's an optional method that lets wxPython know which frame or dialog should be considered the main one. A wxPython program can have several frames, with one designated as the top window for the application. In this case the choice was easy since we have but one frame. ® The final addition to the program represents a common idiom in Python programs used to test whether the module is being run as a program or was imported by another module. We do that by examining the module's __name__ attribute:

If the module was imported, its_name_attribute will be the same as its filename

(without the extension), like this:

'spare'

But if the module is being executed, rather than imported, Python overrides the default naming convention and sets the module's__name__attribute to

'__main__', giving us the chance to have the module behave differently when executed directly. We take advantage of this feature by creating an application instance and entering its main event-loop only if the module is being executed as a program.

If we didn't perform this test, and created an application instance even when this module was imported, it could conflict with code in the module doing the importing—especially if the importing module has already started the wxPython event loop. It would also be quite difficult to test (especially since there can only be one application instance active at one time in a wxPython program, and once we enter the event loop, control passes to wxPython.) By not starting our own application when the module is imported, we make our frame and app classes readily available to other Python programs, facilitating the reuse of existing code.

Was this article helpful?

0 0

Post a comment