I have an application where I need to keep three bitmaps on-hand, and show
one of them in part of the application's frame (the user can change which is
should using radio buttons). I've been doing this with three wx.Bitmap's
for the buffers, and an extra one for the buffer that is currently on
display. Mostly, it works fine. When changing one of the three bitmaps, I
use a wx.MemoryDC:
dc = wx.MemoryDC()
dc.SelectObject(buffers[0])
dc.DrawBitmap(wx.BitmapFromImage(im), 0, 0, False)
del(dc)
The problem is that I sometimes get "wxAssertFailure" errors, with a message
saying "Bitmap is selected in anothre wxMemoryDC, delete the first
wxMemoryDC or use SelectObject(NULL)". I can't find a way to do
dc.SelectObject(NULL) in wx.Python (using "None" does not work), so I use
del(dc). Should this be reliable enough, or do I need to force a garbage
collection pass to make sure it works? I may have some problems in the rest
of the code (maybe my threading logic is not quite right and I'm accidently
doing drawing from with another thread, for example), but currently my
suspicions are that the deletion is not freeing the device context
immediately. I've included my picture window class at the bottom of the
mail in case it is useful.
Many thanks for any hints.
David Brown
Norway
"Utvikling er kunsten av � vikle seg ut av det man har viklet seg inn i"
···
--
picCols = 512
picRows = 512
class PicWin(wx.Window) :
def __init__(self, parent, ID) :
wx.Window.__init__(self, parent, ID, style =
wx.NO_FULL_REPAINT_ON_RESIZE |
wx.SIMPLE_BORDER)
wx.EVT_PAINT(self, self.OnPaint)
self.SetSize((picCols, picRows))
self.buffers = [None] * 3
for i in range(3) :
self.buffers[i] = wx.EmptyBitmap(picCols, picRows)
dc = wx.BufferedDC(None, self.buffers[i])
dc.SetBackground(wx.Brush(wx.WHITE))
dc.Clear()
self.buffer = wx.EmptyBitmap(picCols, picRows)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(wx.WHITE))
dc.Clear()
self.currentBuf = bufRaw
self.minX = 10
self.maxX = 400
self.minY = 50
self.maxY = 500
return
def update(self, line) :
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
dc.BeginDrawing()
dc.DrawBitmap(self.buffers[self.currentBuf].GetSubBitmap(
wx.Rect(0, line, 512, 1)), 0, line, False)
self.refreshLines(dc)
dc.EndDrawing()
del dc
return
def changeBuffer(self, newBuff) :
self.currentBuf = newBuff
self.refreshBuffer()
return
def refreshBuffer(self) :
dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
dc.BeginDrawing()
dc.DrawBitmap(self.buffers[self.currentBuf], 0, 0, False)
self.refreshLines(dc)
dc.EndDrawing()
del dc
return
def refreshLines(self, dc) :
dc.SetPen(wx.Pen(wx.BLUE))
dc.DrawLine(self.minX, 0, self.minX, picRows)
dc.DrawLine(self.maxX, 0, self.maxX, picRows)
dc.DrawLine(0, self.minY, picCols, self.minY)
dc.DrawLine(0, self.maxY, picCols, self.maxY)
return
def OnPaint(self, event) :
dc = wx.BufferedPaintDC(self, self.buffer)
return