I am working on adding threading for updating data aside from the UI in an application I am making.
Under “6. Notes about this example” on this page: https://wiki.wxpython.org/Non-Blocking%20Gui, it says that:
Using events to pass back data will work well in most cases but if you have a or many worker threads that send results at a very rapid rate and in high volume there are better solutions to improve performance and reduce overhead. As handling the high volume of events can once again lead to blocking on the main thread. These other approaches are also not very difficult, I may add a supplemental example at some time if there is interest.
I am wondering how to implement this for high volume of events?
EDIT: Right now I am using wx.PostEvent but the program seems to crash when the worker thread can’t keep up with the events.
It seems that it would be best to stop the data processing in the background halfway through the thread working if there is another event rather than continuing to process before handling the latest event (similar to “bounce” for data entered into an input calling to a web API) but I am not sure how to implement this with wxPython, or if this is the best way to handle this.
Below is what I am doing now:
from threading import * import wx # Define notification event for thread completion EVT_RESULT_ID = wx.NewIdRef() def EVT_RENDER_RESULT(win, func): """ Define result event """ win.Connect(-1, -1, EVT_RESULT_ID, func) class ResultEvent(wx.PyEvent): """ Simple event to carry arbitrary result data """ def __init__(self, data): """Init Result Event.""" wx.PyEvent.__init__(self) self.SetEventType(EVT_RESULT_ID) self.data = data class RenderThread(Thread): """ Thread class that executes processing """ def __init__(self, parent): """ Init the worker thread""" Thread.__init__(self) self._parent = parent # Starts the thread running self.start() def run(self): """ Run the worker thread """ # Code executing in the new thread here. My actually code here is compositing images with Pillow, etc. render_image = # do my stuff here # The result returned wx.PostEvent(self._parent, ResultEvent(render_image))
Main application code:
class MainApplication(wx.Frame): def __init__(self, arguments): wx.Frame.__init__(self, None, title="", size=(1000, 800)) # Indicate we don't have a worker thread yet self.worker = None # Set up event handler for worker thread results EVT_RENDER_RESULT(self, self.OnResult) ... def OnResult(self, event): # Update my stuff here and get the result... # The worker thread is done self.worker = None def Render(self): """ This is the method that is actually called when something is updated """ # Update stuff.... self.worker = RenderThread(self) # From thread.py
render is called too much in a short period of time, the program seems to crash.
Any help is greatly appreciated.