¿Por qué mi solicitud GraphicsContext tamponada tiene un problema de parpadeo?
-
20-09-2019 - |
Pregunta
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()
Yo he llegado con este código para extraer el contenido GraphicsContext doble buffer en un panel, pero hay un parpadeo constante a través de la ventana. He probado diferentes tipos de caminos, al igual que las líneas y curvas, pero es todavía allí y no sé lo que está causando.
Solución
Se obtiene el parpadeo debido a que cada Refresh()
hace que el fondo para ser borrados antes de llamar onPaint
. Es necesario que se unen a EVT_ERASE_BACKGROUND
y convertirlo en un no-op.
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 ...
Otros consejos
Si estás usando un relativamente moderno wxWidgets, puede utilizar wx.BufferedPaintDC
y evitar tener que ensuciar alrededor con la memoria de CC y la pintura y blitting por su cuenta. Además, en las ventanas, FULL_REPAINT_ON_RESIZE menudo provoca el parpadeo incluso cuando usted no está redimensionar la ventana debido a cosas raras pasando bajo las sábanas - si usted no lo necesita, va con NO_FULL_REPAINT_ON_RESIZE puede ayudar. De lo contrario, tendrá que simplificar el código de impresión para asegurarse de que usted puede conseguir la cosa más simple para trabajar, y tal vez echar un vistazo a la DoubleBufferedDrawing página wiki en wxpython.org.