Now I’m thinking using the threading
module might be my goto architecture, and possibly delayedresult
if I need to run an external executable?
I don’t think delayedresult has any special advantage for running external executables, it’s just another cat-skinner. Or IOW, just another way to deal with long-running tasks, whatever they may be. It just happens to be a better fit for some people and how they like to do things. IMO delayedresult is good if you like the pattern of “start something and keep on going while the something is percolating, when it’s done send the result to something else.” It’s similar to a fairly common pattern sometimes associated with names like Future, Deferred, Promise, etc.
Thanks Robin. That makes sense re delayedresult.
My
usual use case is donwloading/uploading info from usb devices, with a progress bar, so delayedresult
doesn’t fit as nicely (of course it does work, but the callback to the consumer is redundant).
The
advantage of wxasync is I can call wx methods directly in asyncio tasks, as they run in the same thread, whereas I need to use wx.CallAfter() when using threads.
One
caveat with wx.CallAfter is you can’t use widget properties - you have to use a callable. e.g. wx.CallAfter( myButton.Label, “g’day” ) needs to be wx.CallAfter( myButton.SetLabel, “g’day” )
wx.CallAfter()
scattered about is little ugly (to me), but not a showstopper by any means. So is there a convenient/clever way to use wx.CallAfter() without explicitly calling it (e.g. via some kind of decorator?). I did
use wxAnyThread in the past with an app, but somewhere along the way it
had a performance impact and I swapped to wx.CallAfter.
Best I can come with is a wrapper function/method to update widgets of interest.
def update_progress( self, value=None, range=None ):
if value != None:
self.gauge.Value = value
if range != None:
self.gauge.Range = range
def update_progress_threadsafe( self, value=None, range=None ):
wx.CallAfter( self.update_progress, value=value, range=range )
``
Is
there some kind of decorator I can apply to update_progress
so I can call it directly from a thread, without having to write a wrapper?