Hello!
I draw a grid, in the cells of which the images (wx.Bitmap) and several rectangles with text (cell numbers) will be located.
I need to use double buffering to get rid of the flickering (the flickering appears when I draw the cursor (a square on the selected cell)).
I noticed that when using double buffering, the EVT_PAINT handler is called even when I hover over the scrollbar. In this case, the animation of the scroll bar (smooth color change) occurs in jerks. Without double buffering, the animation is smooth.
Code
import wx
class PanelDraw(wx.ScrolledCanvas):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.SetDoubleBuffered(True)
self.SetScrollRate(42, 42)
self.cnt = 25
self.padding = 32
self.SetVirtualSize(self.cnt * 64 + 2 * self.padding,
self.cnt * 64 + 2 * self.padding)
self.Bind(wx.EVT_PAINT, self.on_paint)
def on_paint(self, event):
dc = wx.PaintDC(self)
dc.Clear()
self.DoPrepareDC(dc)
gc = wx.GraphicsContext.Create(dc) # type: wx.GraphicsContext
gc.SetBrush(wx.TRANSPARENT_BRUSH)
pen = wx.Pen(wx.Colour(80, 80, 80, 127), 1, wx.PENSTYLE_USER_DASH)
pen.SetDashes([2, 2])
gc.SetPen(pen)
for i in range(self.cnt + 1):
gc.StrokeLine(self.padding + i * 64, self.padding,
self.padding + i * 64, self.padding + self.cnt * 64)
gc.StrokeLine(self.padding, self.padding + i * 64,
self.padding+ self.cnt * 64, self.padding + i * 64)
class Frame(wx.Frame):
def __init__(self):
super().__init__(None)
self.canvas = PanelDraw(self)
if __name__ == '__main__':
app = wx.App()
Frame().Show()
app.MainLoop()
I managed to solve this problem by removing the call to SetDoubleBuffered and also using wx.AutoBufferedPaintDC instead of wx.PaintDC.
But now I am getting strange behavior when drawing a rectangle. After scrolling the page, the old rectangles are not deleted.
Code
import wx
class PanelDraw(wx.ScrolledCanvas):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# self.SetDoubleBuffered(True)
self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.SetScrollRate(42, 42)
self.cnt = 25
self.padding = 32
self.SetVirtualSize(self.cnt * 64 + 2 * self.padding,
self.cnt * 64 + 2 * self.padding)
self.Bind(wx.EVT_PAINT, self.on_paint)
def on_paint(self, event):
dc = wx.AutoBufferedPaintDC(self)
dc.Clear()
self.DoPrepareDC(dc)
gc = wx.GraphicsContext.Create(dc) # type: wx.GraphicsContext
gc.SetBrush(wx.TRANSPARENT_BRUSH)
pen = wx.Pen(wx.Colour(80, 80, 80, 127), 1, wx.PENSTYLE_USER_DASH)
pen.SetDashes([2, 2])
gc.SetPen(pen)
for i in range(self.cnt + 1):
gc.StrokeLine(self.padding + i * 64, self.padding,
self.padding + i * 64, self.padding + self.cnt * 64)
gc.StrokeLine(self.padding, self.padding + i * 64,
self.padding + self.cnt * 64, self.padding + i * 64)
self.draw_angle(dc)
def draw_angle(self, dc: wx.DC):
size_x, size_y = self.GetClientSize()
sx, sy, *_ = dc.GetClippingRect()
dc.SetBrush(wx.Brush(wx.RED))
dc.SetPen(wx.TRANSPARENT_PEN)
dc.DrawRectangle(sx, sy, size_x, 20)
dc.DrawRectangle(sx, sy, 20, size_y)
class Frame(wx.Frame):
def __init__(self):
super().__init__(None)
self.canvas = PanelDraw(self)
if __name__ == '__main__':
app = wx.App()
Frame().Show()
app.MainLoop()
How can I fix this?
Thanks.