2012-07-24 26 views
0

我正在使用wxPython和Cairo編寫的新項目,以便在畫布上動態繪製對象。一切工作都很好,儘管我注意到wxPython有一個很大的警告,我很難解決這個問題。我對wxPython相當陌生,對開羅來說也很新穎,所以答案可能很明顯,但我似乎無法在任何地方找到它。使用開羅和wxPython動態繪圖

我遇到的問題是,當wx.EVT_PAINT被調用時,似乎只能在圖形上下文(wx.GraphicsContext)上繪製,但我需要外部類才能夠輕鬆繪製到畫布上。

我最初的計劃是創建Cairo上下文,然後將其存儲在畫布所在的類中,然後任何需要訪問上下文來繪製的類都可以使用類似canvas.ctx的簡單方法來獲取它。

我的整體問題是,有沒有什麼辦法可以訪問開羅上下文,而無需調用wx.EVT_PAINT?

這裏是我現在有工作代碼:

import wx 
import CairoAPI 

class Canvas(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None, -1, "test", pos=(0, 0), size=(640,480)) 
     #self.ShowFullScreen(1) 
     self.Bind(wx.EVT_PAINT, self.OnPaint) 

    def DrawRectangle(self): 
     pass 

    def OnPaint(self, event): 
     dc = wx.PaintDC(self) 
     w,h = dc.GetSizeTuple() 
     gc = wx.GraphicsContext.Create(dc) 
     nc = gc.GetNativeContext() 
     ctx = CairoAPI.Context_FromSWIGObject(nc) 


if __name__=="__main__": 

    app = wx.App() 
    canvas = Canvas() 
    canvas.Show() 
    app.MainLoop() 

在這段代碼中,我要完成的任務是使canvas.DrawRectangle和必須寫在畫布上沒有的功能之中的能力從畫布內調用。打印。

對不起,如果我讓這個問題混淆。我剛剛開始學習開羅昨晚,我仍然有點不熟悉它的工作原理和一些事情的正確術語。

謝謝!

編輯:我忘了一些代碼:「CairoAPI」模塊是我從教程中得到的東西(不記得哪一個脫手)。這是它的來源。

import ctypes 
import cairo 
from ctypes.util import find_library 

cairo_dll = ctypes.CDLL(find_library("cairo")) 

# Pycairo's API representation (from pycairo.h) 
class Pycairo_CAPI(ctypes.Structure): 
    _fields_ = [ 
     ('Context_Type', ctypes.py_object), 
     ('Context_FromContext', ctypes.PYFUNCTYPE(ctypes.py_object, 
               ctypes.c_void_p, 
               ctypes.py_object, 
               ctypes.py_object)), 
     ('FontFace_Type', ctypes.py_object), 
     ('FontFace_FromFontFace', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('FontOptions_Type', ctypes.py_object), 
     ('FontOptions_FromFontOptions', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('Matrix_Type', ctypes.py_object), 
     ('Matrix_FromMatrix', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('Path_Type', ctypes.py_object), 
     ('Path_FromPath', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('Pattern_Type', ctypes.py_object), 
     ('SolidPattern_Type', ctypes.py_object), 
     ('SurfacePattern_Type', ctypes.py_object), 
     ('Gradient_Type', ctypes.py_object), 
     ('LinearGradient_Type', ctypes.py_object), 
     ('RadialGradient_Type', ctypes.py_object), 
     ('Pattern_FromPattern', ctypes.c_void_p), 
     ('ScaledFont_Type', ctypes.py_object), 
     ('ScaledFont_FromScaledFont', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('Surface_Type', ctypes.py_object), 
     ('ImageSurface_Type', ctypes.py_object), 
     ('PDFSurface_Type', ctypes.py_object), 
     ('PSSurface_Type', ctypes.py_object), 
     ('SVGSurface_Type', ctypes.py_object), 
     ('Win32Surface_Type', ctypes.py_object), 
     ('XlibSurface_Type', ctypes.py_object), 
     ('Surface_FromSurface', ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p)), 
     ('Check_Status', ctypes.PYFUNCTYPE(ctypes.c_int, ctypes.c_int))] 

# look up the API 
ctypes.pythonapi.PyCObject_Import.restype = ctypes.POINTER(Pycairo_CAPI) 
pycairo_api = ctypes.pythonapi.PyCObject_Import("cairo", "CAPI").contents 

ContextType = pycairo_api.Context_Type 

def Context_FromSWIGObject(swigObj): 
    ptr = ctypes.c_void_p(int(swigObj)) 
    #increment the native context's ref count, since the Pycairo_Context decrements it 
    #when it is finalised. 
    cairo_dll.cairo_reference(ptr) 
    return pycairo_api.Context_FromContext(ptr, ContextType, None) 
+0

我也會重新發布到wxPython用戶組。主要的開發者經常使用這個組,並且應該能夠給你一些指示。 – 2012-07-24 20:13:37

+0

感謝您的回覆!我會明確地做到這一點。 – Jeremy 2012-07-24 23:38:20

回答

0

我一樣邁克·德里斯科爾指示我做(in the comment above),並張貼了我的問題上wxPython的組中的兩個開羅郵件列表,並從開羅列表的成員的反應是:

看看wxWindowDC,wxClientDC。

查找這些類之後,我讀:如果一個應用程序希望畫上從OnPaint事件外窗口的客戶區

一個wxClientDC必須構造。這通常應該被構造爲臨時堆棧對象;不要存儲wxClientDC對象。

這正是我一直在尋找的。我希望這有助於任何人在未來遇到同樣的問題。

謝謝! Jeremy Overman

+0

您也可以隨時使用wx.MemoryDC渲染到wx.Bitmap。然後,您可以在EVT_PAINT期間將位圖粘貼到屏幕上。 – FogleBird 2012-07-26 18:50:48