mcfly
mcfly

Reputation: 1151

Call function in wx.frame from different class in Python

There are very similar questions but I'm either not understanding them or they don't quite answer them. The one two I have seen are this one and this one. I have a wxpython GUI running. On the press of a button, I run four different threads (very long running tasks). I have been able to implement this no problem -- the threads run and I can still use the GUI.

Each thread (TestThread0, TestThread1, etc.) writes a variable to a file (but never finishes its loop -- infinite loop). Every so often (say every 20 seconds), I would like to run a function (WriteThis) in my main GUI application (wx.FRAME) that reads this file and its values/variables. My question is how to run this function in the GUI part while the threads are still running? My error comes into play when I try to run TMainForm.WriteThis().

Below is my (very shortened) code:

class TMainForm(wx.Frame):

    def __init__(self, *args, **kwds):


            kwds["style"] = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER
            wx.Frame.__init__(self, *args, **kwds)

            self.Splitter = wx.SplitterWindow(self, -1)#, style=wx.SP_NOSASH)

            self.Panel1 = wx.Panel(self.Splitter, -1)          
            self.Panel3 = wx.Panel(self.Splitter, -1)

            self.Splitter.SplitVertically(self.Panel1,self.Panel3,400)

            ... and so on to set up GUI

    # Press button in GUI to run threads
    def OnAnalyzePress(self,event): 
        TestThread0()
        time.sleep(2)
        TestThread1()
        time.sleep(2)
        TestThread2()
        time.sleep(2)
        TestThread_output

    # This is the function I want to run from TestThread_output class below
    def WriteThis(self):
        print 'Running'
        # I will read file and update GUI here (Threads keep running though)

# Example thread (all the others are the same)
class TestThread0(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.start()    # start the thread

    def run(self):
        # This is my "infinite loop" function that writes variable/values to a file
        MyLongRunningFunction.SomeFunction()

# This is the thread I want to run that executes some function in wx.FRAME every 20 seconds
class TestThread_output(Thread):

    def __init__(self):
        Thread.__init__(self)
        self.start()    # start the thread

    def run(self):

        for i in range(1000):
            TMainForm.WriteThis() # !!! This is where my error is !!! I want to run function called "WriteThis"
            time.sleep(20)

class TApplication(wx.App):
    def OnInit(self):

            wx.InitAllImageHandlers()
            MainForm = TMainForm(None, -1,"")
            self.SetTopWindow(MainForm)

            MainForm.Show()
            return 1

if __name__ == "__main__":
    Application = TApplication(0)
    Application.MainLoop()

Thanks for any help!!

Upvotes: 0

Views: 1136

Answers (1)

Joran Beasley
Joran Beasley

Reputation: 113930

class TestThread_output(Thread):
    def __init__(self,mainForm):
        Thread.__init__(self)
        self.mainForm = mainForm #save reference to the mainFrame GUI
        self.start()    # start the thread
    def run(self):
        for i in range(1000):
            wx.CallAfter(self.mainForm.WriteThis) #since its a diff thread you need callafter(or calllater)
            #I dont think you can do self.mainForm.WriteThis()
            time.sleep(20)

class TMainForm(wx.Frame):
    ...
    def OnAnalyzePress(self,event): 
        TestThread0()
        time.sleep(2)
        TestThread1()
        time.sleep(2)
        TestThread2()
        time.sleep(2)
        TestThread_output(self) #<- pass in this as mainFrame argument to thread constructor

Upvotes: 2

Related Questions