Проблема с Paint Event на Mac OSX 10.8.5 в wxPython
Это прямо сейчас в моем уме. Я относительно новичок в wxPython, и я редактирую чужой код, поэтому, пожалуйста, держите меня в покое. В моей программе у меня есть изображение (растровое изображение), загруженное в 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, возможно? Здесь был задан похожий вопрос: как отправить PaintEvent в wxpython, но это мне не помогло. Я сделал то, что они предложили с self.Refresh(), но у меня появляется та же ошибка. Почему это работает на Windows, а не на Mac? Похоже, что на изображении нет рисунков.
1 ответ
Во-первых, вы не должны обрабатывать событие рисования для собственного виджета. Иногда это будет работать, как в этом случае на Win7, но иногда это не так, и он официально не поддерживается wxWidgets. (Поведение "неопределено")
Во-вторых, зачем красить wx.StaticBitmap
совсем? Если вам нужно изменить растровое изображение, которое отображает виджет, вы можете просто дать ему новое с его SetBitmap
метод. В этом случае, если сетка, которую вы рисуете, является динамической (должна меняться со временем), вы можете использовать wx.MemoryDC
сделать новое растровое изображение с сеткой (IOW, нарисуйте растровое изображение и вызовите drawGrid
на DC памяти), а затем передать этот новый растровый SetBitmap
,
В-третьих, вы обычно не видите звонки event.Skip
в обработчиках событий рисования. Могут быть случаи, когда это может вызвать проблемы, если только базовые классы не ожидают этого.
В-четвертых, это не проблема, а использование wx.BufferedPaintDC
на Mac это лишнее, так как платформа уже выполняет двойную буферизацию. GTK делает это в большинстве случаев. E сть wx.AutoBufferedPaintDC
это будет либо PaintDC
или BufferedPaintDC
в зависимости от того, нужна ли буферизация для данной платформы. Или вы можете решить, какой из них использовать в своем собственном коде, посмотрев на возвращаемое значение window.IsDoubleBuffered()
,
Наконец, если вы предпочитаете решать эту проблему, используя события рисования вместо генерации и замены изображений в wx.StaticBitmap
тогда другой подход, который вы могли бы сделать, это сделать собственный класс, похожий на wx.StaticBitmap
он просто рисует растровое изображение на себе, но также знает, как управлять рисованием сетки, когда это необходимо, тогда вы можете использовать этот класс вместо wx.StaticBitmap
, Вы могли бы использовать wx.lib.statbmp
Модуль в качестве отправной точки.