在wxPython中使用自定义背景时,Panel不会完全刷新

时间:2013-07-04 23:32:42

标签: python wxpython

以下是一些示例代码:

import wx

class MainPanel(wx.Panel):

p1 = None
p2 = None

def __init__(self, parent):

    wx.Panel.__init__(self, parent=parent)

    self.frame = parent
    #self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
    #self.bg = wx.Bitmap("2.jpg")

    self.Bind(wx.EVT_MOTION, self.OnMouseMove)
    self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
    self.Bind(wx.EVT_PAINT, self.OnPaint)

    self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))

def OnMouseMove(self, event):
    if event.Dragging() and event.LeftIsDown():
        self.p2 = event.GetPosition()
        self.Refresh()

def OnMouseDown(self, event):
    self.p1 = event.GetPosition()

def OnPaint(self, event):
    if self.p1 is None or self.p2 is None: return

    dc = wx.PaintDC(self)
    dc.SetPen(wx.Pen('red', 3, wx.LONG_DASH))
    dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.SOLID))
    dc.DrawRectangle(self.p1.x, self.p1.y, self.p2.x - self.p1.x, self.p2.y - self.p1.y)


class MainFrame(wx.Frame):
def __init__(self):
    wx.Frame.__init__(self, None, size=(600,450))
    panel = MainPanel(self)        
    self.Center()

class Main(wx.App):
def __init__(self, redirect=False, filename=None):
    wx.App.__init__(self, redirect, filename)
    dlg = MainFrame()
    dlg.Show()

if __name__ == "__main__":
app = Main()
app.MainLoop()

两条违规行是:

    #self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
    #self.bg = wx.Bitmap("2.jpg")

如果你运行这样的代码,你就可以在面板上绘制一个矩形。如果你开始一个新的矩形,旧的矩形会消失,因为面板是刷新的。

但是,如果取消注释这两行,则在绘制矩形时,它会保留在那里。您可以拥有无​​限数量的矩形。如果我使用dc.Clear(),背景消失并重新加载背景会使应用程序变慢并且它会闪烁。

如何在使用自定义背景时让面板完全刷新?

顺便说一下,背景图片不会加载此代码,但行为是相同的。

编辑:我找到了使用dc.Clear()并重新加载背景导致的闪烁的解决方法。将面板上的双缓冲设置为true可以解决闪烁问题:

self.SetDoubleBuffered(True)

我会使用它,但我会保留问题,以防有人知道最初问题的答案。

1 个答案:

答案 0 :(得分:1)

使用wx.BG_STYLE_CUSTOM背景样式时,它假定您将在EVT_PAINT事件处理程序中绘制(或清除)整个窗口。没有闪烁的最简单方法是每次绘画事件只将像素推到屏幕一次。

使用SetDoubleBuffered在系统级执行此操作,尽管已知在某些情况下会产生副作用。另一种简单的方法是使用wx.BufferedPaintDC而不是wx.PaintDC。它将创建一个位图,该位图是所有绘图操作的目标,然后最终将位图的内容刷新到屏幕。