0

私のプログラムでは、イメージ (ビットマップ) を wxScrolledWindow にロードしています。画像の上にグリッドを描画しようとしていますが、うまくいきません。私の仕事は、このプログラムを最初に開発された Windows から移植し、Mac でも動作させることですが、予想以上に大変な作業です。

def OnPaint(self, event):
    dc = wx.BufferedPaintDC(self.staticBitmap,self.staticBitmap.GetBitmap())
    dc.Clear()
    dc.DrawBitmap(self.wxBitmap, 0, 0)    
    self.drawGrid(dc)
    event.Skip()

def drawGrid(self, dc):
    gridWid, gridHgt = self.staticBitmap.GetBitmap().GetSize()
    numRows, numCols = self.gridSize, self.gridSize
    if self.controlPanel.showGridBox.IsChecked():
        dc.SetPen(wx.Pen(self.gridColor, self.gridThickness))
        dc.SetTextForeground(self.gridColor)
        cellWid = float( gridWid - 1) / numRows
        cellHgt = float( gridHgt - 1) / numCols
        for rowNum in xrange( numRows + 1) :
            dc.DrawLine( 0, rowNum*cellHgt, gridWid, rowNum*cellHgt )
        for colNum in xrange( numCols + 1 ) :
            dc.DrawLine( colNum*cellWid, 0, colNum*cellWid, gridHgt )

このコードは Windows 7 では問題なく動作しますが、Mac で実行すると次のエラーが発生します。

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

self.staticBitmap は wxStaticBitmap であり、self.wxBitmap はまったく同じ画像です。私の推測では、おそらく GraphicsContext と関係があるのでしょうか? ここで同様の質問がありました: wxpython で PaintEvent を送信する方法ですが、これは役に立ちませんでした。彼らが self. Refresh() で提案したことをしましたが、同じエラーが発生しました。Windows では機能するのに、Mac では機能しないのはなぜですか? 画像に描画が行われていないようです。

4

1 に答える 1

2

まず、ネイティブ ウィジェットのペイント イベントを処理するべきではありません。この Win7 の場合のように機能する場合もありますが、機能しない場合もあり、wxWidgets では公式にサポートされていません。(動作は「未定義」です)

第二に、なぜわざわざ絵を描くのwx.StaticBitmapですか?ウィジェットが表示しているビットマップを変更する必要がある場合は、SetBitmapメソッドを使用して新しいビットマップを与えることができます。この場合、描画しているグリッドが動的である場合 (時間の経過とともに変更する必要がある場合)、 aを使用wx.MemoryDCしてグリッドを使用して新しいビットマップを作成し (IOW、ビットマップを描画drawGridしてメモリ DC を呼び出す)、その新しいビットマップを渡すことができます。にSetBitmap

event.Skip第 3 に、ペイント イベント ハンドラでの呼び出しは通常見られません。基本クラスが予期していない限り、これも問題を引き起こす可能性がある場合があります。

第 4 に、それは実際には問題ではありませんがwx.BufferedPaintDC、プラットフォームが既にすべてをダブル バッファリングしているため、Mac での使用は不要です。GTK もほとんどの場合そうします。特定のプラットフォームでバッファリングが必要かどうかに応じて、またはのwx.AutoBufferedPaintDCいずれかになる があります。または、 の戻り値を見て、独自のコードでどちらを使用するかを決定できます。PaintDCBufferedPaintDCwindow.IsDoubleBuffered()

最後に、画像を生成してスワップするのではなく、ペイント イベントを使用してこの問題を処理したい場合は、別の方法として、それ自体にビットマップを描画するだけでなく、描画を管理する方法も知っているwx.StaticBitmapカスタム クラスを作成することもできます。wx.StaticBitmapグリッドが必要な場合は、そのクラスを の代わりに使用できますwx.StaticBitmapwx.lib.statbmpモジュールを出発点として使用できます。

于 2015-01-27T17:29:19.960 に答える