<div class="gmail_quote"><p>Hi! 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.</p>
<p>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.</p>
<p>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.</p>
<p>My overall question is, is there any way that I can have access to the Cairo Context without needing wx.EVT_PAINT being calling?</p>
<p>Here's the code I'm working with right now:</p>
<pre><code><span>import</span><span> wx<br></span><span>import</span><span> </span><span>CairoAPI</span><span><br><br></span><span>class</span><span> </span><span>Canvas</span><span>(</span><span>wx</span><span>.</span><span>Frame</span><span>):</span><span><br>
</span><span>def</span><span> __init__</span><span>(</span><span>self</span><span>):</span><span><br> wx</span><span>.</span><span>Frame</span><span>.</span><span>__init__</span><span>(</span><span>self</span><span>,</span><span> </span><span>None</span><span>,</span><span> </span><span>-</span><span>1</span><span>,</span><span> </span><span>"test"</span><span>,</span><span> pos</span><span>=(</span><span>0</span><span>,</span><span> </span><span>0</span><span>),</span><span> size</span><span>=(</span><span>640</span><span>,</span><span>480</span><span>))</span><span><br>
</span><span>#self.ShowFullScreen(1)</span><span><br> </span><span>self</span><span>.</span><span>Bind</span><span>(</span><span>wx</span><span>.</span><span>EVT_PAINT</span><span>,</span><span> </span><span>self</span><span>.</span><span>OnPaint</span><span>)</span><span><br>
<br> </span><span>def</span><span> </span><span>DrawRectangle</span><span>(</span><span>self</span><span>):</span><span><br> </span><span>pass</span><span><br>
<br> </span><span>def</span><span> </span><span>OnPaint</span><span>(</span><span>self</span><span>,</span><span> </span><span>event</span><span>):</span><span><br>
dc </span><span>=</span><span> wx</span><span>.</span><span>PaintDC</span><span>(</span><span>self</span><span>)</span><span><br>
w</span><span>,</span><span>h </span><span>=</span><span> dc</span><span>.</span><span>GetSizeTuple</span><span>()</span><span><br>
gc </span><span>=</span><span> wx</span><span>.</span><span>GraphicsContext</span><span>.</span><span>Create</span><span>(</span><span>dc</span><span>)</span><span><br>
nc </span><span>=</span><span> gc</span><span>.</span><span>GetNativeContext</span><span>()</span><span><br> ctx </span><span>=</span><span> </span><span>CairoAPI</span><span>.</span><span>Context_FromSWIGObject</span><span>(</span><span>nc</span><span>)</span><span><br>
<br><br></span><span>if</span><span> __name__</span><span>==</span><span>"__main__"</span><span>:</span><span><br><br> app </span><span>=</span><span> wx</span><span>.</span><span>App</span><span>()</span><span><br>
canvas </span><span>=</span><span> </span><span>Canvas</span><span>()</span><span><br> canvas</span><span>.</span><span>Show</span><span>()</span><span><br>
app</span><span>.</span><span>MainLoop</span><span>()</span><span><br></span></code></pre>
<p>In this code, what I want to accomplish is to make
canvas.DrawRectangle have the ability to write to the canvas without
the function being called from within canvas.OnPaint.</p><p>Also, I used code from a tutorial I read, and made module out of it, thus CairoAPI. The code for it is as follows:</p><pre><code><span>import</span><span> ctypes<br>
</span><span>import</span><span> cairo<br></span><span>from</span><span> ctypes</span><span>.</span><span>util </span><span>import</span><span> find_library<br>
<br>cairo_dll </span><span>=</span><span> ctypes</span><span>.</span><span>CDLL</span><span>(</span><span>find_library</span><span>(</span><span>"cairo"</span><span>))</span><span><br>
<br></span><span># Pycairo's API representation (from pycairo.h)</span><span><br></span><span>class</span><span> </span><span>Pycairo_CAPI</span><span>(</span><span>ctypes</span><span>.</span><span>Structure</span><span>):</span><span><br>
_fields_ </span><span>=</span><span> </span><span>[</span><span><br> </span><span>(</span><span>'Context_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Context_FromContext'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span><br>
ctypes</span><span>.</span><span>c_void_p</span><span>,</span><span><br> ctypes</span><span>.</span><span>py_object</span><span>,</span><span><br>
ctypes</span><span>.</span><span>py_object</span><span>)),</span><span><br> </span><span>(</span><span>'FontFace_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'FontFace_FromFontFace'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'FontOptions_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'FontOptions_FromFontOptions'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'Matrix_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Matrix_FromMatrix'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'Path_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Path_FromPath'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'Pattern_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'SolidPattern_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'SurfacePattern_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Gradient_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'LinearGradient_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'RadialGradient_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Pattern_FromPattern'</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>),</span><span><br>
</span><span>(</span><span>'ScaledFont_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'ScaledFont_FromScaledFont'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'Surface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'ImageSurface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'PDFSurface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'PSSurface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'SVGSurface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Win32Surface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'XlibSurface_Type'</span><span>,</span><span> ctypes</span><span>.</span><span>py_object</span><span>),</span><span><br>
</span><span>(</span><span>'Surface_FromSurface'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>py_object</span><span>,</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>)),</span><span><br>
</span><span>(</span><span>'Check_Status'</span><span>,</span><span> ctypes</span><span>.</span><span>PYFUNCTYPE</span><span>(</span><span>ctypes</span><span>.</span><span>c_int</span><span>,</span><span> ctypes</span><span>.</span><span>c_int</span><span>))]</span><span><br>
<br></span><span># look up the API</span><span><br>ctypes</span><span>.</span><span>pythonapi</span><span>.</span><span>PyCObject_Import</span><span>.</span><span>restype </span><span>=</span><span> ctypes</span><span>.</span><span>POINTER</span><span>(</span><span>Pycairo_CAPI</span><span>)</span><span><br>
pycairo_api </span><span>=</span><span> ctypes</span><span>.</span><span>pythonapi</span><span>.</span><span>PyCObject_Import</span><span>(</span><span>"cairo"</span><span>,</span><span> </span><span>"CAPI"</span><span>).</span><span>contents<br>
<br></span><span>ContextType</span><span> </span><span>=</span><span> pycairo_api</span><span>.</span><span>Context_Type</span><span><br>
<br></span><span>def</span><span> </span><span>Context_FromSWIGObject</span><span>(</span><span>swigObj</span><span>):</span><span><br> ptr </span><span>=</span><span> ctypes</span><span>.</span><span>c_void_p</span><span>(</span><span>int</span><span>(</span><span>swigObj</span><span>))</span><span><br>
</span><span>#increment the native context's ref count, since the Pycairo_Context decrements it</span><span><br> </span><span>#when it is finalised.</span><span><br>
cairo_dll</span><span>.</span><span>cairo_reference</span><span>(</span><span>ptr</span><span>)</span><span><br> </span><span>return</span><span> pycairo_api</span><span>.</span><span>Context_FromContext</span><span>(</span><span>ptr</span><span>,</span><span> </span><span>ContextType</span><span>,</span><span> </span><span>None</span><span>)</span><span><br>
</span></code></pre><p></p><p>Sorry if I've made this question confusing. I just started learning
Cairo last night and I'm still a little unfamiliar with how it works and
the correct terminology for some things.</p>
<p>Thank you!</p>
</div><br>