There are many ways to use threads with wxPython efficiently. One of them is using custom events and triggering them from threads. The Code below shows a simplified way to do it.
Note:Triggered event handler runs in the main thread.
#!/usr/bin/python # encoding: utf-8 import threading import time import random import wx import wx.lib.newevent ItemActivated, EVT_ITEM_ACTIVATED = wx.lib.newevent.NewEvent() class WorkerThread(threading.Thread): def __init__(self, mypanel, range_): self.mypanel = mypanel self.range = range_ threading.Thread.__init__(self) def run(self): count = 0 while count < 5: time.sleep(1) wx.PostEvent(self.mypanel, ItemActivated(data=random.randint(*self.range), thread=threading.current_thread())) count += 1 class MyPanel(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent, -1) self.sizer = wx.BoxSizer(wx.VERTICAL) worker_thread1 = WorkerThread(mypanel=self, range_=(1, 100)) worker_thread1.daemon = True worker_thread2 = WorkerThread(mypanel=self, range_=(1000, 2000)) worker_thread2.daemon = True worker_thread1.start() worker_thread2.start() self.mystatic_text = wx.StaticText(self, -1, label="In Main Thread") self.sizer.Add(self.mystatic_text) self.Bind(EVT_ITEM_ACTIVATED, self.on_item_activated) self.SetSizerAndFit(self.sizer) def on_item_activated(self, evt): old_label = self.mystatic_text.GetLabel() self.mystatic_text.SetLabel(old_label + "\n->Event Triggered From %s with data %s" % (evt.thread, evt.data)) if __name__ == "__main__": app = wx.App() frame = wx.Frame(None, title="wx.PostEvent Example with Threads", size=(650, 400)) MyPanel(frame) frame.CenterOnScreen() frame.Show() app.MainLoop()
Discussion