How to send PaintEvent in wxpython

2019-08-15 18:21发布

问题:

I'm trying to generate a PaintEvent in wxpython to trigger redrawing a window. However, I can't seem to make it work, I get errors because I try to use a PaintDC outside of a native paint event.

Here is a minimal example:

import wx

class AppFrame(wx.Frame):
    def __init__(self):
        super(AppFrame, self).__init__(parent=None, title="Demo")
        self.SetClientSize((800,600))

        self.Bind(wx.EVT_PAINT, self.paint)

        self.Bind(wx.EVT_LEFT_DOWN, self.onclick)

    def onclick(self, event):
        wx.PostEvent(self,wx.PaintEvent())

    def paint(self, event=None):
        print "paint"
        dc = wx.PaintDC(self)
        dc.SetPen(wx.Pen(wx.BLACK, 4))
        dc.DrawLine(0, 0, 50, 50)

if __name__ == "__main__":
    app = wx.App(redirect=False)
    appFrame = AppFrame()
    appFrame.Show()
    app.MainLoop()

I know I could call Refresh() in the onclick handler to get the same functionality (and use CallAfter to make it threadsafe), but I would like to understand why I can't send PaintEvents.

I'm on Mac OS 10.7 with wxpython 3.0.1.1, Python 2.7.1. The error I get is

  File "test.py", line 17, in paint
    dc = wx.PaintDC(self)
  File "/usr/local/lib/wxPython-3.0.0.0/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_gdi.py", line 5122, in __init__
    _gdi_.PaintDC_swiginit(self,_gdi_.new_PaintDC(*args, **kwargs))
wx._core.PyAssertionError: C++ assertion "window->MacGetCGContextRef() != NULL" failed at /BUILD/wxPython-src-3.0.0.0/src/osx/carbon/dcclient.cpp(195) in wxPaintDCImpl(): using wxPaintDC without being in a native paint event

回答1:

Calling the window's Refresh method will trigger a paint event, by marking the window or a subrectangle of it as "damaged". The system will then send a paint event as soon as it can, with all of the "damaged" regions added together in the event's update region. If you want the paint event to happen immediately instead of waiting for the system you can then call the window's Update method, however usually the right thing to do is to just wait for the system to send it naturally.



标签: wxpython