wxpython requires that some things be called from the main thread. This can be accomplished via calls to wx.CallAfter
or wx.CallLater
or by creating and posting your own custom event. wx.TextCtrl.SetValue
appears to be thread safe. There are several examples of how to implement threads with wxpython, but here's another:
# tested on windows 10, python 3.6.8
import wx, threading, time
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Test Frame", wx.DefaultPosition, (500, 500))
self.tc = wx.TextCtrl(self, -1, "Click button to start thread...", size=(500, 350), style=wx.TE_MULTILINE)
self.button = wx.Button(self, label="Click to start thread", pos=(0, 360))
self.button.SetSize(self.button.GetBestSize())
self.button.CenterOnParent(wx.HORIZONTAL)
self.thread = None
self.button.Bind(wx.EVT_BUTTON, self.on_button)
self.Show()
def on_button(self, event):
self.thread = threading.Thread(target=self.threaded_method)
self.thread.start()
def threaded_method(self):
self.tc.SetValue("thread has started.....")
time.sleep(1.5)
for n in range(5, 0, -1):
self.tc.SetValue(f"thread will exit in {n}")
time.sleep(1)
self.tc.SetValue("thread has finished")
app = wx.App()
frame = MainFrame()
app.MainLoop()