Search code examples
pythonwxpythonpyopengl

My wx.OnPaint() function is not called constantly in the wx main loop


I working on a project using OpenGL and wxPython to make a navigatable 3D user interface. However, the OnPaint() function doesn't seem to be called continuously in the main loop. That makes my interface not being updated constantly. The function is only called I drag around the window. For example: when I press an arrow key, the object in the window only moves when I drag around the window.

I boiled my code down to these lines of codes. Can anyone help me make the OnPaint() function called constantly in print a bunch of "HI" without the need to drag around the window?

if __name__ == "__main__":
    app = MyApp()
    app.MainLoop()
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame()
        frame.Show()
        return True

class MyFrame(wx.Frame):
    def __init__(self):
        self.size = (1000, 700)
        wx.Frame.__init__(self, None, title ="wx", size=self.size)
        self.canvas = MyCanvas(self)
class MyCanvas(GLCanvas):

    def __init__(self, parent):
        GLCanvas.__init__(self, parent, -1, size=(1000, 700))
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, event):
        print("HI")

Solution

  • A wx.Window like wx.Frame or GLCanvascan be forced to be repainted by .Refresh().
    e.g. You can use the wx.IdleEvent to triggers the canvas to be refreshed continuously.

    class MyFrame(wx.Frame):
        def __init__(self):
            self.size = (1000, 700)
            wx.Frame.__init__(self, None, title ="wx", size=self.size)
            self.canvas = MyCanvas(self)
            self.Bind(wx.EVT_IDLE, self.OnIdle)
    
        def OnIdle(self, event):
            self.Refresh()         # refresh self and all its children
            #self.canvas.Refresh() # refresh self.canvas