title: Why does the formatting of my wxPython widget get fouled up?
body: <p>I have written a wxPython application (following documentation) which just about does everything I want it to. It has checkboxes and textlines etc. all the way I want it. The only problem is that I made this as the main frame of my application. </p>
  
  <p>What I really want is to turn this into a widget so that I can instantiate a few of them in my final application frame. However, when I tried to make my widget inherit from wx.Panel rather than wx.Frame and then instantiate one into my Frame class, it collapsed on itself like a neutron star.</p>
  
  <p>Please take a look at my two code examples and see if you know what went wrong.</p>
  
  <p>This is the version where my widget is built directly in the class which inherits from wx.Frame: </p>
  
  <pre><code>#!/usr/bin/env python
  
  """
  This demo attempts to override the C++ MainLoop and implement it
  in Python.
  """
  
  import time
  import wx
  import serial                
  from serial.tools.list_ports import comports
  
  #str1 = '[12:28:14]fxn_name() ***ISCFLAGS***1***0***0***0***3.19***00-1C-FA-F1-00-09-F1-EE***\r\n'
  logAll = 1
  
  """lowBat1 = 0
  pir1 = 0
  batVolt1 = 0
  tamp1 = 0
  supervise1 = 0
  mac1 = 0"""
  ######################################################################################
  class ETL_test(wx.Frame):
      def __init__(self, parent, id, title):
          wx.Frame.__init__(self, parent, id, title, size=(275, 200))
          self.initGUI()
          self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
          self.Show()
  
      def initGUI(self):
          #main container panel for all of the ISC status information
          self.checkBoxPanel = wx.Panel(self,-1,size=(100,200),style= wx.SUNKEN_BORDER)
  
          self.checkBoxVbox = wx.BoxSizer(wx.VERTICAL)
  
          #make the three individual checkboxes
          self.superviseCheck = wx.CheckBox(self.checkBoxPanel,-1,'Supervisory Trouble')
          self.pirCheck = wx.CheckBox(self.checkBoxPanel,-1,'PIR Activity')
          self.tamperCheck = wx.CheckBox(self.checkBoxPanel,-1,'Tamper Tripped')
  
          #make the MAC hbox section
          self.macHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.macLabel = wx.StaticText(self.checkBoxPanel,-1,'MAC ADDR: ')
          macFont1 = wx.Font(10, wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_BOLD)
          self.macLabel.SetFont(macFont1)
          macFont2 = wx.Font(10, wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL)
          self.macAddr = wx.StaticText(self.checkBoxPanel,-1,'001CFAF10009F1EE')
          self.macAddr.SetFont(macFont2)
          self.macHbox.Add(self.macLabel,0,wx.RIGHT,5)
          self.macHbox.Add(self.macAddr,0,0,0)
  
          #make the low battery hbox section
          self.lowBatCheck = wx.CheckBox(self.checkBoxPanel,-1,'Low Battery Voltage')
          self.batVoltText = wx.StaticText(self.checkBoxPanel,-1, '9.9V')
          self.lowBatHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.lowBatHbox.Add(self.lowBatCheck, 0,wx.RIGHT,20)
          self.lowBatHbox.Add(self.batVoltText, 0,wx.ALL,0)
  
          #make the pirCount hbox section
          self.pirCountHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.pirCountNumber = 3
          self.pirLabel = wx.StaticText(self.checkBoxPanel,-1,'PIR Count: ')
          self.pirCount = wx.StaticText(self.checkBoxPanel,-1,str(self.pirCountNumber))
          self.pirReset = wx.Button(self.checkBoxPanel,-1,label='Reset PIR Count')
          self.pirCountHbox.Add(self.pirLabel,0,wx.RIGHT,3)
          self.pirCountHbox.Add(self.pirCount,0,wx.RIGHT, 40)
          self.pirCountHbox.Add(self.pirReset,0,wx.ALIGN_RIGHT,0)
          self.pirReset.Bind(wx.EVT_BUTTON,self.resetPIR)
  
          #add all the parts to the main vbox
          self.checkBoxVbox.Add(self.macHbox,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.superviseCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.lowBatHbox,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.tamperCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.pirCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.pirCountHbox,0,wx.ALL,5)
          self.checkBoxPanel.SetSizer(self.checkBoxVbox)
  
          #setup the 1 sec timer to update all the data based on the global data
          #self.updateTimer = wx.Timer(self)
          #self.Bind(wx.EVT_TIMER,self.updateData,self.updateTimer)
          #self.updateTimer.Start(500)
  
      #The event handler for pushing the PIR reset button
      def resetPIR(self,event):
          self.pirCountNumber = 0
          self.pirCount.SetLabel(str(self.pirCountNumber))
          self.Show()
  
      #The event handler for the 1 sec timer to update the data fields based on last flags msg
  ##    def updateData(self,event):
  ##        global batVolt1
  ##        self.pirCountNumber += 1;
  ##        self.pirCount.SetLabel(str(self.pirCountNumber))
  ##        self.batVoltText.SetLabel(str(batVolt1)+'V')
  
      #The event handler for closing the window
      def OnCloseWindow(self, event):
          app.keepGoing = False
          self.Destroy()
          logFile.close()
  
      def updateOnSerial(self,flags):
          self.superviseCheck.SetValue(flags[0] == 1)
          self.pirCheck.SetValue(flags[1] == 1)
          if flags[1] == 1:
              self.pirCountNumber += 1
          self.pirCount.SetLabel(str(self.pirCountNumber))
          self.tamperCheck.SetValue(flags[2] == 1)
          self.lowBatCheck.SetValue(flags[3] == 1)
          self.batVoltText.SetLabel(str(flags[4])+'V')
          self.macAddr.SetLabel(str(flags[5]))
  
  #####################################################################################
  
  class MyApp(wx.App):
      def MainLoop(self):
          # Create an event loop and make it active
          evtloop = wx.EventLoop()
          old = wx.EventLoop.GetActive()
          wx.EventLoop.SetActive(evtloop)
  
          # This outer loop determines when to exit the application
          while self.keepGoing:
              # call_my_code_here()
              line = ser.readline()
              parsedLines = line.split('***')
              global logAll
              if len(parsedLines) &gt; 4 and parsedLines[1] == 'ISCFLAGS': #got a flags msg
                  print('Now parsing a ISCFLAGS msg!')
                  self.parseFlagsMsg(parsedLines)
                  logFile.write(str(line))
              elif logAll &gt; 0 and len(parsedLines) &lt; 2: #logAll is on and it's not a flags msg
                  logFile.write(str(line))
              # This inner loop will process any GUI events
              # until there are no more waiting.
              while evtloop.Pending():
                  evtloop.Dispatch()
  
              # Send idle events to idle handlers. 
              # I'll just snooze a little...
              time.sleep(0.10)
              self.ProcessIdle()
  
          wx.EventLoop.SetActive(old)
  
      def parseFlagsMsg(self):
          global lowBat1
          global pir1
          global batVolt1
          global tamp1
          global supervise1
          global mac1
          if len(parsedLines) != 10:
              print('ERROR: not enough flag tokens!!')
              return False
          else:
              camID = parsedLines[2];#1,2, or 3
          # TODO: array of testApps... testApp[camID].updateOnSerial()
          # This passes the 4th element through the 8th element
          testApp.updateOnSerial(parsedLines[3:8]) 
  
      def OnInit(self):
          testApp = ETL_test(None, -1, "Alarm.com 2GIG Image Sensor ETL Test Application")
          testApp.Show(True)
          self.SetTopWindow(testApp)
  
          self.keepGoing = True
          return True
  
  app = MyApp(False)
  logFile = open('C:/Python26/temp/test.txt', 'w')
  ser = serial.Serial('com5',115200,timeout=0.01)
  app.MainLoop()
  </code></pre>
  
  <p>And then here is the version where I tried to make it a custom widget and then instantiate one of them in my wx.Frame class:</p>
  
  <pre><code>#!/usr/bin/env python
  
  """
  This demo attempts to override the C++ MainLoop and implement it
  in Python.
  """
  
  import time
  import wx
  import serial                
  from serial.tools.list_ports import comports
  
  str1 = '[12:28:14]fxn_name() ***ISCFLAGS***1***0***0***0***3.19***00-1C-FA-F1-00-09-F1-EE***\r\n'
  logAll = 1
  
  """lowBat1 = 0
  pir1 = 0
  batVolt1 = 0
  tamp1 = 0
  supervise1 = 0
  mac1 = 0"""
  #---------------------------------------------------------------------------       
  class ISC_status(wx.Panel):
      def __init__(self, parent, id):
          wx.Panel.__init__(self, parent, id, size=(275, 200))
          self.initGUI()
          #self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
          self.Show()
  
      def initGUI(self):
          #main container panel for all of the ISC status information
          self.checkBoxPanel = wx.Panel(self,-1,size=(100,200),style= wx.SUNKEN_BORDER)
  
          self.checkBoxVbox = wx.BoxSizer(wx.VERTICAL)
  
          #make the three individual checkboxes
          self.superviseCheck = wx.CheckBox(self.checkBoxPanel,-1,'Supervisory Trouble')
          self.pirCheck = wx.CheckBox(self.checkBoxPanel,-1,'PIR Activity')
          self.tamperCheck = wx.CheckBox(self.checkBoxPanel,-1,'Tamper Tripped')
  
          #make the MAC hbox section
          self.macHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.macLabel = wx.StaticText(self.checkBoxPanel,-1,'MAC ADDR: ')
          macFont1 = wx.Font(10, wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_BOLD)
          self.macLabel.SetFont(macFont1)
          macFont2 = wx.Font(10, wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL)
          self.macAddr = wx.StaticText(self.checkBoxPanel,-1,'001CFAF10009F1EE')
          self.macAddr.SetFont(macFont2)
          self.macHbox.Add(self.macLabel,0,wx.RIGHT,5)
          self.macHbox.Add(self.macAddr,0,0,0)
  
          #make the low battery hbox section
          self.lowBatCheck = wx.CheckBox(self.checkBoxPanel,-1,'Low Battery Voltage')
          self.batVoltText = wx.StaticText(self.checkBoxPanel,-1, '9.9V')
          self.lowBatHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.lowBatHbox.Add(self.lowBatCheck, 0,wx.RIGHT,20)
          self.lowBatHbox.Add(self.batVoltText, 0,wx.ALL,0)
  
          #make the pirCount hbox section
          self.pirCountHbox = wx.BoxSizer(wx.HORIZONTAL)
          self.pirCountNumber = 3
          self.pirLabel = wx.StaticText(self.checkBoxPanel,-1,'PIR Count: ')
          self.pirCount = wx.StaticText(self.checkBoxPanel,-1,str(self.pirCountNumber))
          self.pirReset = wx.Button(self.checkBoxPanel,-1,label='Reset PIR Count')
          self.pirCountHbox.Add(self.pirLabel,0,wx.RIGHT,3)
          self.pirCountHbox.Add(self.pirCount,0,wx.RIGHT, 40)
          self.pirCountHbox.Add(self.pirReset,0,wx.ALIGN_RIGHT,0)
          self.pirReset.Bind(wx.EVT_BUTTON,self.resetPIR)
  
          #add all the parts to the main vbox
          self.checkBoxVbox.Add(self.macHbox,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.superviseCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.lowBatHbox,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.tamperCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.pirCheck,0,wx.ALL,5)
          self.checkBoxVbox.Add(self.pirCountHbox,0,wx.ALL,5)
          self.checkBoxPanel.SetSizer(self.checkBoxVbox)
  
          #setup the 1 sec timer to update all the data based on the global data
          #self.updateTimer = wx.Timer(self)
          #self.Bind(wx.EVT_TIMER,self.updateData,self.updateTimer)
          #self.updateTimer.Start(500)
  
      #The event handler for pushing the PIR reset button
      def resetPIR(self,event):
          self.pirCountNumber = 0
          self.pirCount.SetLabel(str(self.pirCountNumber))
          self.Show()
  
      #The event handler for the 1 sec timer to update the data fields based on last flags msg
  ##    def updateData(self,event):
  ##        global batVolt1
  ##        self.pirCountNumber += 1;
  ##        self.pirCount.SetLabel(str(self.pirCountNumber))
  ##        self.batVoltText.SetLabel(str(batVolt1)+'V')
  
  
  
      def updateOnSerial(self,flags):
          self.superviseCheck.SetValue(flags[0] == 1)
          self.pirCheck.SetValue(flags[1] == 1)
          if flags[1] == 1:
              self.pirCountNumber += 1
          self.pirCount.SetLabel(str(self.pirCountNumber))
          self.tamperCheck.SetValue(flags[2] == 1)
          self.lowBatCheck.SetValue(flags[3] == 1)
          self.batVoltText.SetLabel(str(flags[4])+'V')
          self.macAddr.SetLabel(str(flags[5]))
  #---------------------------------------------------------------------------
  class ETL_test(wx.Frame):
      def __init__(self, parent, id, title):
          wx.Frame.__init__(self, parent, id, title, size=(275, 200))
          self.initGUI()
          self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
          self.Show()
  
      def initGUI(self):
          panel = wx.Panel(self)
          ISC1 = ISC_status(self,-1)
          sizer = wx.BoxSizer(wx.VERTICAL)
          sizer.Add(ISC1,1,wx.ALL|wx.EXPAND,5)
          panel.SetSizer(sizer)
          self.Layout()
          self.Show()
  
      #The event handler for closing the window
      def OnCloseWindow(self, event):
          app.keepGoing = False
          self.Destroy()
          logFile.close()
  #---------------------------------------------------------------------------
  
  class MyApp(wx.App):
      def MainLoop(self):
          # Create an event loop and make it active
          evtloop = wx.EventLoop()
          old = wx.EventLoop.GetActive()
          wx.EventLoop.SetActive(evtloop)
  
          # This outer loop determines when to exit the application
          while self.keepGoing:
              # call_my_code_here()
              line = ser.readline()
              parsedLines = line.split('***')
              global logAll
              if len(parsedLines) &gt; 4 and parsedLines[1] == 'ISCFLAGS': #got a flags msg
                  print('Now parsing a ISCFLAGS msg!')
                  self.parseFlagsMsg(parsedLines)
                  logFile.write(str(line))
              elif logAll &gt; 0 and len(parsedLines) &lt; 2: #logAll is on and it's not a flags msg
                  logFile.write(str(line))
              # This inner loop will process any GUI events
              # until there are no more waiting.
              while evtloop.Pending():
                  evtloop.Dispatch()
  
              # Send idle events to idle handlers. 
              # I'll just snooze a little...
              time.sleep(0.10)
              self.ProcessIdle()
  
          wx.EventLoop.SetActive(old)
  
      def parseFlagsMsg(self):
          global lowBat1
          global pir1
          global batVolt1
          global tamp1
          global supervise1
          global mac1
          if len(parsedLines) != 10:
              print('ERROR: not enough flag tokens!!')
              return False
          else:
              camID = parsedLines[2];#1,2, or 3
          # TODO: array of testApps... testApp[camID].updateOnSerial()
          # This passes the 4th element through the 8th element
          testApp.updateOnSerial(parsedLines[3:8]) 
  
      def OnInit(self):
          testApp = ETL_test(None, -1, "Alarm.com 2GIG Image Sensor ETL Test Application")
          testApp.Show(True)
          self.SetTopWindow(testApp)
  
          self.keepGoing = True
          return True
  
  app = MyApp(False)
  logFile = open('C:/Python26/temp/test.txt', 'w')
  ser = serial.Serial('com5',115200,timeout=0.01)
  app.MainLoop()
  </code></pre>
  
  <p>To reiterate: the first code sample works basically as I want, but that needs to be a single widget in my eventual program. Why when I try to instantiate that in a class which inherits from wx.Frame does the formatting just disappear and everything is located on top of each other?</p>
  
  <p>Thanks in advance for your help. Let me know if there is any other information I need to provide.</p>