Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
183 views
in Technique[技术] by (71.8m points)

python - Scroll bar animations when using double buffering

I am drawing a grid in the cells of which the images will be located (wx.Bitmap).

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 wxEVT_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.

Is there a way to solve this problem?

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()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I managed to solve this problem by removing the call to SetDoubleBuffered and also using wx.AutoBufferedPaintDC instead of wx.PaintDC.

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)
 
 
class Frame(wx.Frame):
 
    def __init__(self):
        super().__init__(None)
 
        self.canvas = PanelDraw(self)
 
 
if __name__ == '__main__':
    app = wx.App()
    Frame().Show()
    app.MainLoop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...