I'm designing an application with a GUI made with wxPython. It has basically a frame embedding a notebook with many tabs. Each tab is a panel class. For instance on one tab I've an ObjectListView widget and some pyplot graphs. I'd like to have the full tab refreshed every x milliseconds as the data are updated in background.
What is the proper way ? Refreshing the full panel or individually each widget ?
Shall a panel class include a while True like you would do for a thread ? or using events ? If anyone could highlight this or point me to a webpage indicating how to do that would be very helpful. I guess I'm not searching with the correct keywords as I don't find really suitable descriptions on how to manage this....
Thanks Stephane
You have to create a Timer object and also overwrite the OnPaint event if you want to draw something. Bind the Timer object to an update method, this will be called periodically, 60 times in a second (1/60). I will paste below an old code of mine which draws a circle in the upper left corner. If you press the Move button, the circle will move diagonally to the lower right. So I guess if it works on one Panel, it should also work with multiple Panels.
import wx
class MyPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.Bind(wx.EVT_PAINT, self.OnPaint)
# create a timer
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update, self.timer)
# start x, y position of the circle
self.x, self.y = 0, 0
# refresh rate
self.delta = 1/60
self.SetDoubleBuffered(True)
btn1 = wx.Button(self, wx.ID_ANY, u"Move", size=(100, 50), pos=(800, 100))
self.Bind(wx.EVT_BUTTON, self.start_simulation, btn1)
def start_simulation(self, evt):
self.timer.Start(self.delta)
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.SetBrush(wx.Brush('#c56c00'))
dc.DrawEllipse(self.x, self.y, 60, 60)
# dc.DrawEllipse(0, 20, 60, 60)
dc.DrawLine(0, 600, 800, 600)
def update(self, evt):
self.x += 2
self.y += 2
self.Refresh()
class MyFrame(wx.Frame):
def __init__(self):
self.size = (1280, 720)
super().__init__(None, title="Moving circle", size=self.size, style=wx.DEFAULT_FRAME_STYLE)
self.panel = MyPanel(self)
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame()
frame.Show()
return True
if __name__ == "__main__":
app = MyApp()
app.MainLoop()