I’m trying to update the 5 cells in the second row of the ListCtrl every 0.5 seconds from the worker thread, but none of the 5 cells gets updated until 5*0.5 seconds later.
I googled for hours and was surprised that there’s no (obvious) canonical solution for this problem. On Android, runOnUiThread
is a no-brainer.
I would like to ask what’s the right way to do it, or where’s the right place to look for solutions.
Many thanks.
import wx
from wx.lib.newevent import NewEvent
import subprocess
import threading
MyEvent, MY_EVENT = NewEvent()
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None)
self.panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.list_ctrl = wx.ListCtrl(self.panel, wx.ID_ANY, style=wx.LC_HRULES | wx.LC_REPORT | wx.LC_VRULES)
sizer.Add(self.list_ctrl, 1, wx.EXPAND)
self.btn = wx.Button(self.panel, wx.ID_ANY, "button")
self.btn.Bind(wx.EVT_BUTTON, self.on_btn)
sizer.Add(self.btn)
self.panel.SetSizer(sizer)
self.Layout()
self.Bind(MY_EVENT, self.on_my_event)
def add_data(self):
for i in range(5):
self.list_ctrl.AppendColumn(f"col{i}")
for i in range(3):
self.list_ctrl.Append([f"init{i}-{j}" for j in range(5)])
def on_btn(self):
threading.Thread(target=self._do_on_btn).run()
def _do_on_btn(self):
# run on another thread
for i in range(5):
subprocess.run(["sleep", "0.5"])
wx.PostEvent(self, MyEvent(i=i))
def on_my_event(self, evt):
self.list_ctrl.SetItem(1, evt.i, f"new1-{evt.i}")
self.list_ctrl.Refresh()
self.list_ctrl.Update()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame()
self.frame.add_data()
self.SetTopWindow(self.frame)
self.frame.Show()
return True
def main():
app = MyApp()
app.MainLoop()
main()