Issue with Paint Event on Mac OSX 10.8.5 in wxPython

Here is my original post from stackoverflow which may be easier to view than attaching the text file:
https://stackoverflow.com/questions/28156821/issue-with-paint-event-on-mac-osx-10-8-5-in-wxpython

I am having an issue with using any type of PaintDC in my program. I am actually editing an old intern’s code and my job is to make sure this works on Mac. My entire program works just fine on Windows, and I have made some adjustments for it to work on Mac visually but for some reason I keep on getting this error when I try to draw on top of a bitmap:

Traceback (most recent call last):
File "/Users/kyra/Documents/workspace/ADAPT/src/GUI.py", line 1617, in OnPaint
dc = wx.BufferedPaintDC(self.staticBitmap, self.staticBitmap.GetBitmap())
File "/usr/local/lib/wxPython-3.0.2.0/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_gdi.py", line 5290, in __init__
_gdi_.BufferedPaintDC_swiginit(self,_gdi_.new_BufferedPaintDC(*args, **kwargs))
wx._core.PyAssertionError: C++ assertion "window->MacGetCGContextRef() != NULL" failed at /BUILD/wxPython-src-3.0.2.0/src/osx/carbon/dcclient.cpp(195) in wxPaintDCImpl(): using wxPaintDC without being in a native paint event

I have no idea what this error means. The only time I don’t get an error is when I use a GraphicsContext, which is why I assume I need to use a GCDC on a Mac, but I don’t know how to translate the wxBufferedPaintDC over to a GCDC. I’m very new to using paint events so I’m assuming the previous intern used the buffered paint DC for a reason. I’m not even sure how my program doesn’t error when I have wxBufferedPaintDC(self.staticBitmap, self.statBitmap.GetBitmap()) because self.staticBitmap is not a window, but a wxStaticBitmap.

Any suggestions? This has been a huge headache as everything else has transferred over to Mac fairly well.

kjhrabal@eckerd.edu wrote:

Here is my original post from stackoverflow which may be easier to view
than attaching the text file:
python - Issue with Paint Event on Mac OSX 10.8.5 in wxPython - Stack Overflow

Answered at StackOverflow. Some additional info and answers below.

I am having an issue with using any type of PaintDC in my program. I am
actually editing an old intern's code and my job is to make sure this
works on Mac. My entire program works just fine on Windows, and I have
made some adjustments for it to work on Mac visually but for some reason
I keep on getting this error when I try to draw on top of a bitmap:

>Traceback (most recent call last):
File "/Users/kyra/Documents/workspace/ADAPT/src/GUI.py", line1617, in OnPaint
dc= wx.BufferedPaintDC(self.staticBitmap, self.staticBitmap.GetBitmap())
File "/usr/local/lib/wxPython-3.0.2.0/lib/python2.7/site-packages/wx-3.0-osx_cocoa/wx/_gdi.py", line5290, in __init__
_gdi_.BufferedPaintDC_swiginit(self,_gdi_.new_BufferedPaintDC(*args, **kwargs))
wx._core.PyAssertionError: C++ assertion"window->MacGetCGContextRef() != NULL" failed at/BUILD/wxPython-src-3.0.2.0/src/osx/carbon/dcclient.cpp(195) in wxPaintDCImpl(): using wxPaintDC without beingin a native paint event|

I have no idea what this error means.

It means that you can't paint on a wx.StaticBitmap because the Mac is not giving us (wx) a valid CGContext (the native equivalent for a DC or GraphicsContext) for the native widget.

The only time I don't get an error
is when I use a GraphicsContext, which is why I assume I need to use a
GCDC on a Mac, but I don't know how to translate the wxBufferedPaintDC
over to a GCDC.

Although this isn't true on other platforms the wx.DCs are already almost the same as wx.GCDCs on Mac.

I'm very new to using paint events so I'm assuming the
previous intern used the buffered paint DC for a reason.

To help prevent flicker, but as I outlined in the SO response it was a flawed approach to take in this case. Either generating and/or switching bitmaps in the wx.StaticBitmap, or making a custom widget class that draws the bitmap itself are better ways to do this.

I'm not even
sure how my program doesn't error when I have
wxBufferedPaintDC(self.staticBitmap, self.statBitmap.GetBitmap())
because self.staticBitmap is not a window, but a wxStaticBitmap.

A wx.StaticBitmap is a wx.Window, because if you follow the class hierarchy you'll find wx.Window is a base class. So yes, because of the class hierarchy wxWidgets allows you to pass a wx.StaticBitmap where a wx.Window is the parameter type, but in this case the platform is rejecting it because it doesn't want you to draw directly on this kind of native widget.

···

--
Robin Dunn
Software Craftsman