Error while creating an object of an other class in a class of type Thread in Python
Question: Level: Beginner

I am using python v2.7 and wxPython v3.0 on windows 7 32-bit.

**My app** : I have 3 classes. One class is `gui(wx.Frame)` and other is
`TestThread(Thread)` and the third is `labels()`.

**Problem** : I am trying to create an object of the `gui(wx.Frame)` class in
`TestThread(Thread)` class, but I am getting an error as given below:

    
    
    Traceback (most recent call last):
      File "C:\test\post.py", line 11, in <module>
        class TestThread(Thread):
      File "C:\test\post.py", line 12, in TestThread
        guiObj = gui()
    NameError: name 'gui' is not defined
    

However if I try to call the `createPanels()` of `gui(wx.Frame)` class from
the `TestThread(Thread)` class like this `wx.CallAfter(gui().createPanels())`
then I get following error:

    
    
    Exception in thread Thread-1:
    Traceback (most recent call last):
      File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
        self.run()
      File "C:\test\post.py", line 24, in run
        wx.CallAfter(gui().createPanels())
    TypeError: __init__() takes exactly 4 arguments (1 given)
    

I think the reason is something related to the `__init__()` of the
`gui(wx.Frame)` I didn't understand the reason.

**Update:** I tried to create an object of `labels()` class in
`TestThread(Thread)` class, I get the same error as shown in first case above.
Is there something special about this `TestThread(Thread)` class?

The complete code is provided below and can be [downloaded
here](https://db.tt/ZjqgqJwH) to avoid identation problems:

    
    
    #!/usr/bin/env python
    
    from random import randrange
    import wx
    import wx.lib.scrolledpanel
    from threading import Thread
    from wx.lib.pubsub import setuparg1
    from wx.lib.pubsub import pub as Publisher
    ##################################################
    class TestThread(Thread):
         guiObj = gui()
    
         def __init__(self):
            Thread.__init__(self)
            self.start()    # start the thread
    
         def run(self):
            wx.CallAfter(guiObj.createPanels())
            time.sleep(5)
    
    ##############################################
    class gui(wx.Frame):
    
        def __init__(self, parent, id, title):
            screenWidth = 800
            screenHeight = 450
            screenSize = (screenWidth, screenHeight)
            wx.Frame.__init__(self, None, id, title, size=screenSize)
            self.locationFont = locationFont = wx.Font(15, wx.MODERN, wx.NORMAL, wx.BOLD)
            mainSizer = wx.BoxSizer(wx.VERTICAL)
            self.sizer = sizer = wx.BoxSizer(wx.VERTICAL)
            self.panel = panel = wx.lib.scrolledpanel.ScrolledPanel(self, -1, style=wx.SIMPLE_BORDER)
            panel.SetupScrolling()
            panel.SetBackgroundColour('#FFFFFF')
            panel.SetSizer(sizer)
            mainSizer.Add(panel, 15, wx.EXPAND|wx.ALL)
            self.SetSizer(mainSizer)
    
        def createPanels(self):
           k = 0
           labelObj = labels()
           locations = labelObj.getLabel()
           print locations
           for i in locations:
               sPanels = 'sPanel'+str(k)
               sPanels = wx.Panel(self.panel)
               label = str(k+1)
               text = wx.StaticText(sPanels, -1, label0)
               text.SetFont(self.locationFont)
               text.SetForegroundColour('#0101DF')
               self.sizer.Add(sPanels, 0, wx.ALL, 5)
               self.sizer.Add(wx.StaticLine(self.panel), 0, wx.ALL|wx.EXPAND, 0)
               k += 1
    
       TestThread()
    ################################################
    class labels():
        def getLabel(self):
           mylist =[]
           i = randrange(10)
           for k in range(1,i+1):
               mylist.append(k)
           return mylist
    ###############################################
    
    if __name__=='__main__':
       app = wx.App()
       frame = gui(parent=None, id=-1, title="Test")
       frame.Show()
       app.MainLoop()
    

Thank you for your time!


Answer: **For the first issue:**

`guiObj = gui()` is executed when Python first runs the file, which causes two
problems:

  * Python does not know about `gui` when executing it
  * All instances of `TestThread` will have the same `gui` instance

To fix both of them, you have to put `guiObj = gui()` in the constructor of
`TestThread`

If you only want to fix the first one, put the declaration of `gui` before the
declaration of `TestThread`.

**For the second issue:**

Using `gui()` is wrong because the constructor of `gui` takes three arguments
(four actually, but the first one is implicit. You have to call it with three
arguments, like you did at the end of the program: `gui(parent=None, id=-1,
title="Test")`

