I have a wx Gui that gathers all the necessary info and starts an external command line app. Whilst it is running my gui freezes as you'd expect so I've been experimenting with putting the external app in a thread of its own.

My original code ends with the line:

os.system(args)

args contains the path and parameters required. Works fine.
So here is the bit of threading code nicked from an online tutorial:

class AVCThread(Thread):
    """Test Worker Thread Class."""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self.start()    # start the thread
 
    #----------------------------------------------------------------------
    def run(self):
        """Run Worker Thread."""
        # This is the code executing in the new thread.

        os.system(args)
        wx.CallAfter(Publisher().sendMessage, "update", "Processing completed")

This will work if I make args a global and substitute AVCThread() for the original os.system(args). But that is limiting and, I believe, frowned upon. Otherwise how would I get the value of args from the Gui class into the thread class. Or am I approaching this all wrong. I haven't yet found a threads tutorial that is explicit enough... Thanks.

Recommended Answers

All 6 Replies

I think you'll find that most people hate using globals. I would probaly add an argument to the __init__ method to accept the args:

def __init__(self, args):
      self.args = args

and then simply pass those saved arguments in your 'run' method.

def run(self):
   os.system(self.args)

Just pass the args to the thread when you create the instance

worker_thread = AVCThread(args)

Thanks for the help.
I think I must be missing the point as I just get "global args is not defined"

... you have to define args.
args = WhatArgsWasGoingToEqualInYourProgram

args is defined it is the path to the external program.
This is how the thread bit now looks:

class ProcessThread(Thread):
    """Test Worker Thread Class."""
 
    #----------------------------------------------------------------------
    def __init__(self, args):
        self.args = args
        """Init Worker Thread Class."""
        Thread.__init__(self)
        self.start()    # start the thread
        print args
    #----------------------------------------------------------------------
    def run(self):
        """Run Worker Thread."""
        print args
        os.system(args)
        wx.CallAfter(Publisher().sendMessage, "update", "Processing completed")

The first print statement is correct, the second one is not defined.

You didn't use the code sample I posted. Use self.args, not just args. When an instance of ProcessThread is created it saves the argument 'args' to itself. You can access it from the class by invoking 'self.args' anytime after the instance has been created. Or from outside the instance by

instance = ProcessThread(args)
print instance.args

Got it! Thanks for your patience.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.