Introduction

Splitting code out into modules generally makes for a more organized program, but how do you test the modules without running the entire program? This page attempts to provide some suggestions on how to code modules to allow them to run as stand-alone programs.

Basics

Python sets the __name__ variable to __main__ for the main module of any Python application. By testing this variable, we can determine whether the module was run stand-alone or not.

Simple Example

This allows us to do something like the following:

import wx

class MyFrame(wx.Frame):
    """Module frame definition goes here"""

    def __init__(self,parent,id,title):
        wx.Frame.__init__(self,parent,id,title)

class App(wx.App):
    """Class used to run module as __main__"""

    def OnInit(self):
        frame = MyFrame(None,-1,"Testing")
        frame.Show()
        self.SetTopWindow(frame)
        return True

def main():
    app = App(redirect=0)
    app.MainLoop()

if __name__ == '__main__':
    main()

The code from class App(wx.App): to the end of the file is what allows this module to be run as a stand-alone program. It says that if this is the main module, create a wx.App and show me MyFrame. The module App class will need to be modified depending on the type of class you are putting into this module.

Advanced Example

What if you want to view individual panel layouts rather than full frames? Try the following:

import wx

class MyPanel(wx.Panel):
    """Module panel definition goes here"""

    def __init__(self,parent,id):
        wx.Panel.__init__(self,parent,id)

        self.sizer = wx.FlexGridSizer(2,2,0,0)

        for i in range(1,5):
            t = wx.StaticText(self,-1,'Field '+`i`,style=wx.ALIGN_CENTER)
            self.sizer.Add(t,proportion=1,border=5,flag=wx.ALL|wx.GROW)

        self.sizer.AddGrowableCol(1)

        self.SetAutoLayout(True)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)

class App(wx.App):
    """Class used to run module as __main__"""

    def OnInit(self):
        frame = wx.Frame(None,-1,"Testing")
        panel = MyPanel(frame,-1)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(panel,proportion=1,flag=wx.GROW)

        frame.SetAutoLayout(True)
        frame.SetSizer(sizer)
        sizer.Fit(frame)

        frame.Show()
        self.SetTopWindow(frame)
        return True

def main():
    app = App(redirect=0)
    app.MainLoop()

if __name__ == '__main__':
    main()

In order to get the sizer functions to work properly, it appears that there must be a chain of sizers from the parent window to all of the children. That is why there is a BoxSizer placed on the frame. Notice the use of sizer.Fit() in both the panel and the frame. Try commenting out sizer.Fit() in the panel class and see what happens.

Comments

DebuggingModules (last edited 2008-03-11 10:50:36 by localhost)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.