Creating Cairo context causes recursion

Hello,

I’ve been trying to draw custom gauges via wxPython using the standard graphics context, and while this is straightforward, it’s fairly tedious. I was hoping to design the gauges with an SVG editor like Inkscape, load them into a custom
wx.PyControl, and animate the moving parts to speed up the design process. From some googling, it looks like Cairo integration and librsvg is the most common solution. My control is pretty standard and renders properly with the standard graphics context
drawing. The most relevant (I think) part of the code follows:

def OnPaint(self, event):

dc = wx.BufferedPaintDC(self)

dc.SetBackground(wx.Brush(‘gray’))

dc.Clear()

self.Draw(dc)

def Draw(self, dc):

width, height = self.GetClientSize()

if not width or not height:

return

ctx = wx.lib.wxcairo.ContextFromDC(dc)

print “Context:”, ctx

ctx.paint()

When is runs, I get a small white box on a black background, and as soon as the first redraw occurs, I receive the following error over and over again rapidly:

RuntimeError: maximum recursion depth exceeded while calling a Python object

Exception RuntimeError: ‘maximum recursion depth exceeded while calling a Python object’ in ignored

Traceback (most recent call last):

File “C:_PROJECTS\advanced_gauge\gauge.py”, line 45, in OnPaint

dc = wx.BufferedPaintDC(self)

RuntimeError

Cairo seems available because the following sets hasCairo to True:

try:

import wx.lib.wxcairo

import cairo

haveCairo = True

except ImportError:

haveCairo = False

I have been following the example at
http://xy-27.pythonxy.googlecode.com/hg-history/0b7c0c0bd5a5cc63dcc505285052e210b126ab0b/src/python/wxPython/DOC/demo/Cairo.py
. I am using Python 2.7 x32 on Windows 7 x64 with wx.version = 2.8.12.1.

Would appreciate any tips or suggestions on how to debug this or better approach the problem.

Thanks,

Louis

Louis Simons wrote:

Hello,

I�ve been trying to draw custom gauges via wxPython using the standard
graphics context, and while this is straightforward, it�s fairly
tedious. I was hoping to design the gauges with an SVG editor like
Inkscape, load them into a custom wx.PyControl, and animate the moving
parts to speed up the design process. From some googling, it looks like
Cairo integration and librsvg is the most common solution. My control is
pretty standard and renders properly with the standard graphics context
drawing. The most relevant (I think) part of the code follows:

[...]

When is runs, I get a small white box on a black background, and as soon
as the first redraw occurs, I receive the following error over and over
again rapidly:

RuntimeError: maximum recursion depth exceeded while calling a Python object

Exception RuntimeError: 'maximum recursion depth exceeded while calling
a Python object' in ignored

Traceback (most recent call last):

File "C:\_PROJECTS\advanced_gauge\gauge.py", line 45, in OnPaint

dc = wx.BufferedPaintDC(self)

RuntimeError

My guess is that it may be a combination of errors, and that the true source of the problem maybe being obscured by the flood of recursion depth exceptions. So try to capture the first few exceptions and see if that sheds any more light on it.

One thing to be aware of is that on Windows if there is not a paint DC created for a window that has an EVT_PAINT then the system will assume that the paint event still needs to be handled so it will resend the event right away. So if there is an issue with constructing the wx.BufferedPaintDC then the immediate resend could be part of the problem.

Also, of course, a recursion depth problem means that something is causing the flow of control to come back around to the same place, which then triggers a new cycle, and so on until all of the stack space is consumed. So in this case look for things that your code is doing that could cause another paint event to be sent before the first one is finished.

Finally, make sure that the self in OnPaint is the same window which is binding the EVT_PAINT.

If none of the above helps you, then please make a runnable, small as possible, sample application that demonstrates the problem. MakingSampleApps - wxPyWiki

···

--
Robin Dunn
Software Craftsman

Louis Simons wrote:

Hello,

I�ve been trying to draw custom gauges via wxPython using the standard

graphics context, and while this is straightforward, it�s fairly

tedious. I was hoping to design the gauges with an SVG editor like

Inkscape, load them into a custom wx.PyControl, and animate the moving

parts to speed up the design process. From some googling, it looks like

Cairo integration and librsvg is the most common solution. My control is

pretty standard and renders properly with the standard graphics context

drawing. The most relevant (I think) part of the code follows:

[…]

When is runs, I get a small white box on a black background, and as soon

as the first redraw occurs, I receive the following error over and over

again rapidly:

RuntimeError: maximum recursion depth exceeded while calling a Python object

Exception RuntimeError: 'maximum recursion depth exceeded while calling

a Python object’ in ignored

Traceback (most recent call last):

File “C:_PROJECTS\advanced_gauge\gauge.py”, line 45, in OnPaint

dc = wx.BufferedPaintDC(self)

RuntimeError

My guess is that it may be a combination of errors, and that the true
source of the problem maybe being obscured by the flood of recursion
depth exceptions. So try to capture the first few exceptions and see if
that sheds any more light on it.

One thing to be aware of is that on Windows if there is not a paint DC
created for a window that has an EVT_PAINT then the system will assume
that the paint event still needs to be handled so it will resend the
event right away. So if there is an issue with constructing the
wx.BufferedPaintDC then the immediate resend could be part of the problem.

Also, of course, a recursion depth problem means that something is
causing the flow of control to come back around to the same place, which
then triggers a new cycle, and so on until all of the stack space is
consumed. So in this case look for things that your code is doing that
could cause another paint event to be sent before the first one is finished.

Finally, make sure that the self in OnPaint is the same window which is
binding the EVT_PAINT.

If none of the above helps you, then please make a runnable, small as
possible, sample application that demonstrates the problem.
http://wiki.wxpython.org/MakingSampleApps

It seems like I had a bad library installed. After updating everything to the latest versions, I was able to make the linked simplified app draw an SVG via a simplified test app. It renders the SVG to a bitmap array before transferring it to a wx.StaticBitmap. However, since this doesn’t use the buffered graphicscontext, I get flickering during draws. Should it be possible to render directly to the graphics context?

···

On Monday, June 24, 2013 9:04:58 PM UTC-4, Robin Dunn wrote:


Robin Dunn

Software Craftsman

http://wxPython.org

It seems like I had a bad library installed. After updating everything to the latest versions, I was able to make the linked simplified app draw an SVG via a simplified test app. It renders the SVG to a bitmap array before transferring it to a wx.StaticBitmap. However, since this doesn’t use the buffered graphicscontext, I get flickering during draws. Should it be possible to render directly to the graphics context?

I was able to simplify it to rendering directly on the DC at https://gist.github.com/superlou/5885625 (test_directly_to_dc.py). Hope it’s useful to somebody. Next up is trying to manipulate the SVG DOM for animation.

Thanks,

Louis

···