“”
The code below worked great in wxPython 3.X under Python 2.7 and earlier.
Below is only the drawing portion of this program.
It has been modified simply to make it Python 3.x and wxPython 4.x compatable.
I had to upgrade to wxPython 4.0.7 gtk2.
Prior to this I always got an error that said that both wx.Window objects in the code below were not valid DC’s.
Now the code works “sort of”.
After initially drawing correctly, the only way I can get an redrawn plot is by physically resizing the GUI (using the mouse).
I have tried faking it out by forceing a window resize from within the code.
In this case, I always get an Infinite loop of resizeing calls.
So far no matter how I write this code (double buffered or not) or even calling OnResize from within OnPaint makes no difference.
Am missing something, doing something wrong, or are there still bugs.
Clearly, there were in the DC code before I upgraded from wxPython 4.0.1 to 4.0.7
“”"
class SpectraPlot(wx.Window):
“”"
A simplifed spectra ploting class
“”"
def __init__(self, parent, pos, size, name="plotframe", ppPos = (125,50), ppSizeDiff = (200,150), style = wx.NO_FULL_REPAINT_ON_RESIZE):
wx.Window.__init__(self, parent=parent, id=wx.ID_ANY, pos=pos, size=size, name=name, style=style)
self.SetBackgroundColour(ct.LIGHT_GREY)
self.SD_Color = [ct.GREEN, ct.RED, ct.BLUE, ct.CYAN, ct.ORANGE, ct.LIGHT_STEEL_BLUE]
self.parent = parent
self.frame = parent
self.pos = pos
fpx, fpy = self.pos
self.size = size
fsx, fsy = self.size
self.xOffset = ppPos[0]
self.yOffset = ppPos[1]
self.xSizediff = ppSizeDiff[0]
self.ySizediff = ppSizeDiff[1]
ppPos=(self.xOffset,self.yOffset)
ppSize=(fsx-self.xSizediff, fsy-self.ySizediff)
self.plotpanel = wx.Window(self, wx.ID_ANY, pos=ppPos, size=ppSize, style = wx.BORDER, name ="plotpanel")
self.plotpanel.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.plotpanel.SetBackgroundColour(wx.WHITE)
self.Bind(wx.EVT_SIZE, self.OnResize)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.plotpanel.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
self.plotpanel.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
self.plotpanel.Bind(wx.EVT_MOTION, self.OnMouseMotion)
self.plotpanel.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
>>>>>
def InitBuffers(self):
self.plotframeSize = self.GetSize()
(self.xW, self.yH) = self.plotframeSize
self.ppW = self.xW-self.xSizediff
self.ppH = self.yH-self.ySizediff
self.plotpanel.SetSize((self.ppW, self.ppH))
self._plotbuffer = wx.Bitmap((self.ppW, self.ppH))
if USE_BUFFER:
dc = wx.BufferedPaintDC(self.plotpanel, self._plotbuffer)
else:
dc = wx.MemoryDC()
dc.SelectObject(self._plotbuffer)
dc.SetBackground(wx.Brush(self.plotpanel.GetBackgroundColour()))
dc.Clear()
self._framebuffer = wx.Bitmap(self.plotframeSize)
if USE_BUFFER:
“”"
This does not seem to work only the MemoryDC approach below works. This is different from the older wxPython3.x and Python2.7.x where the BufferedPaintDC approach is the one I used. But I do not think this is the issue with repainting.
“”"
fdc = wx.BufferedPaintDC(self, self._framebuffer)
else:
fdc = wx.MemoryDC()
fdc.SelectObject(self._framebuffer)
fdc.SetBackground(wx.Brush(self.GetBackgroundColour()))
fdc.Clear()
self.drawAxis(dc, fdc)
try:
self.UpperLeft = (self.xEq.minPix, self.yEq.minPix)
self.LowerRight = (self.xEq.maxPix, self.yEq.maxPix)
except:
ft.line_comment("Exception when plotting data")
self.plot(dc)
if self.drawbox:
self.drawEmptyBox(dc)
def plot(self, dc, color = None):
"""
Plot the data if it exists
"""
ft.line_comment("In my_plotlib.plot")
ideal_calc = wx.FindWindowByName("ideal_calc")
if not color:
color = wx.BLACK_PEN
if self.Spec_Data and ideal_calc.SD_Flag:
ideal_calc.reg_data.Enable()
pixel = self.getSpec_data(self.Spec_Data)
dc.SetPen(wx.Pen(self.SD_Color[(self.SD2plot +1) % 6]))
dc.DrawLines(pixel)
else:
self.scale = 1.0
ideal_calc.reg_data.Disable()
data = self.Data
IC_flag = ideal_calc.Data_Flag
if data and (len(data) > 0) and IC_flag:
pixel = self.getPix()
dc.SetPen(color)
dc.DrawLines(pixel)
if len(self.LLmarkers) > 0: #LineList markers
for marker in self.LLmarkers:
(mark, color) = marker
dc.SetPen(wx.Pen(color))
xPix = self.xEq.calcPix(mark)
dc.DrawLine(xPix, self.UpperLeft[1], xPix, self.LowerRight[1])
if len(self.markers) > 0:
for marker in self.markers:
(mark, color) = marker
dc.SetPen(wx.Pen(color))
xPix = self.xEq.calcPix(mark)
dc.DrawLine(xPix, self.UpperLeft[1], xPix, self.LowerRight[1])
def OnPaint(self, evt):
"""
repaint screen
Note that both the commented out BufferedPaintDC calls below work as well and produce the same results
"""
ft.line_comment("In my_plotlib.OnPaint")
fdc = wx.BufferedPaintDC(self, self._framebuffer)
fdc = wx.PaintDC(self)
fdc.DrawBitmap(self._framebuffer, 0, 0)
dc = wx.BufferedPaintDC(self.plotpanel, self._plotbuffer)
dc = wx.PaintDC(self.plotpanel)
dc.DrawBitmap(self._plotbuffer, 0, 0)
evt.Skip()
def OnResize(self, evt):
ft.line_comment("In my_plotlib.OnResize")
self.setLines((self.wave_min, self.wave_max))
evt.Skip()