Dynamic Drawing with Cairo and wxPython

I’m very pleased to see all the quick replies! I believe the method I am going to go with is what Robin Dunn sugested: To create a drawing surface and have it drawn to screen on paint events. Everyone elses suggestions will definitely stick with me. I’m wondering if there will be any noticeable performance drawbacks using this method. In the end, I’m planning on having fairly simple animations using Cairo that will require fairly quick rendering.
Also, I asked this same question on the Cairo mailing list, and the response I got was to look at wxWindowDC and wxClientDC, and looking at the wiki, wxClientDC states that:
“A wxClientDC must be constructed if an application wishes to paint on the
client area of a window from outside an OnPaint event.
This should normally be constructed as a temporary stack object; don’t store
a wxClientDC object.”

This seems to be what I want to do, though I’m a little confused about how to implement that. Would I call wxClientDC from within the function that needs to draw to the Cairo surface? Honestly, I’m a still a little confused as to how the device context works. I’ll definitely have to do a little more research on it before I jump in and tackle a big project.

Thanks for all the help guys! I truly appreciate it.

Jeremy Overman

···

On Tuesday, July 24, 2012 7:43:39 PM UTC-4, Jeremy wrote:

Hi! I’m not sure if this question is more pertained to wxPython, or Cairo, but I figured you guys may be able to help me out here.
I’m working on a new project that is written using wxPython and Cairo
in order to dynamically draw objects on a canvas. Everything works pretty well, though I’m noticing a big caveat with wxPython that I’m having a hard time working around. I’m am fairly new to wxPython, and very new to Cairo, so the answer may be obvious, but I can’t seem to find it anywhere.

The problem I’m running into is that it seems that you are only able to draw on the graphics context (wx.GraphicsContext, I believe) when wx.EVT_PAINT is called, though I need external classes to be able to draw to the canvas easily.

My original plan was to create the Cairo context then store it in the
class that the canvas is on, then any class that needs access to the context to draw would simple get it using something like canvas.ctx.

My overall question is, is there any way that I can have access to the Cairo Context without needing wx.EVT_PAINT being calling?

Here’s the code I’m working with right now:

[snip]

I'm very pleased to see all the quick replies! I believe the method I am
going to go with is what Robin Dunn sugested: To create a drawing surface
and have it drawn to screen on paint events.

Probably the way to go, yes.

Though one question -- why use Cairo at all, rather than wx.GraphicsContext?

performance drawbacks using this method. In the end, I'm planning on having
fairly simple animations using Cairo that will require fairly quick
rendering.

it should be pretty quick

Also, I asked this same question on the Cairo mailing list, and the response
I got was to look at wxWindowDC and wxClientDC, and looking at the wiki,
wxClientDC states that:

"A wxClientDC must be constructed if an application wishes to paint on the
client area of a window from outside an OnPaint event. This should normally
be constructed as a temporary stack object; don't store a wxClientDC
object."

This seems to be what I want to do,

well, the current best practice is to do all your drawing in a Paint
Event -- both when the system asks for it (the usual case), or by
forcing one, with .Update()

That way the system can optimize the drawing pipeline for you. So I"d
stick with the PaintDC for this.

though I'm a little confused about how
to implement that. Would I call wxClientDC from within the function that
needs to draw to the Cairo surface?

whether it's a PaintDC or CleintDC, it's the same -- all you are doing
with the DC is drawing a bitmap -- that's it -- it's totally
independent of Cairo's drawing

You are suing Cairo to do all your drawing to a bitmap in memory

You are using a PaintDC to render that Bitmap to the screen.

That's it -- pretty simple really.

I don't think there are any examples of this in the Wiki, but take a
look at the pages with "Drawing" in the title. In particular the
DoubleBufferedDrawing page is actually quite close to what you want to
do except that you are using CAiro to draw to the off-screen bitmap,
rather than a wx.MemoryDC.

-Chris

···

On Wed, Jul 25, 2012 at 3:25 PM, Jeremy <jeremyoverman@overmanscomputers.com> wrote:

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov