1
import wx

class MainFrame(wx.Frame):
    def __init__(self,parent,title):

        wx.Frame.__init__(self, parent, title=title, size=(640,480))
        self.mainPanel=DoubleBufferTest(self,-1)

        self.Show(True)

class DoubleBufferTest(wx.Panel):
    def __init__(self,parent=None,id=-1):
        wx.Panel.__init__(self,parent,id,style=wx.FULL_REPAINT_ON_RESIZE)

        self.SetBackgroundColour("#FFFFFF")

        self.timer = wx.Timer(self)
        self.timer.Start(100)        
        self.Bind(wx.EVT_TIMER, self.update, self.timer)
        self.Bind(wx.EVT_PAINT,self.onPaint)


    def onPaint(self,event):
        event.Skip()
        dc = wx.MemoryDC()
        dc.SelectObject(wx.EmptyBitmap(640, 480))
        gc = wx.GraphicsContext.Create(dc)
        gc.PushState()
        gc.SetBrush(wx.Brush("#CFCFCF"))
        bgRect=gc.CreatePath()
        bgRect.AddRectangle(0,0,640,480)
        gc.FillPath(bgRect)    
        gc.PopState()

        dc2=wx.PaintDC(self)
        dc2.Blit(0,0,640,480,dc,0,0)
    def update(self,event):
        self.Refresh()

app = wx.App(False)
f=MainFrame(None,"Test")
app.MainLoop()

我想出了这段代码来将双缓冲的 GraphicsContext 内容绘制到面板上,但是窗口上总是闪烁。我尝试了不同类型的路径,比如直线和曲线,但它仍然存在,我不知道是什么原因造成的。

4

2 回答 2

2

你会得到闪烁,因为每个都会Refresh()导致背景在调用之前被擦除onPaint。您需要绑定EVT_ERASE_BACKGROUND并使其成为无操作。

class DoubleBufferTest(wx.Panel):
    def __init__(self,parent=None,id=-1):
        # ... existing code ...
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.onErase)
    def onErase(self, event):
        pass
    # ... existing code ...
于 2010-03-19T16:36:53.197 回答
1

如果您使用的是相对现代的 wxWidgets,您可以使用wx.BufferedPaintDC并避免不得不自行处理内存 DC 以及绘画和 blitting。此外,在 Windows 上,FULL_REPAINT_ON_RESIZE 经常会导致闪烁,即使您由于幕后发生的有趣事情而没有调整窗口大小 - 如果您不需要它,使用 NO_FULL_REPAINT_ON_RESIZE 可能会有所帮助。否则,您将需要简化代码以确保您可以使用最简单的方法,也许可以查看 wxpython.org 上的DoubleBufferedDrawing wiki 页面。

于 2010-03-16T07:47:21.060 回答