问题描述
我正在图像所在的单元格中绘制网格 (wx.Bitmap
)。
我需要使用双缓冲来消除闪烁(当我绘制光标(所选单元格上的正方形)时出现闪烁)。
我注意到使用双缓冲时,即使我将鼠标悬停在滚动条上,也会调用 wxEVT_PAINT
处理程序。在这种情况下,滚动条的动画(平滑的颜色变化)发生在抽搐中。没有双缓冲,动画流畅。
有没有办法解决这个问题?
代码:
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,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+ 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()
解决方法
我通过删除对 SetDoubleBuffered
的调用并使用 wx.AutoBufferedPaintDC
而不是 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,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 + 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()