0

这是一些示例代码:

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)

我会使用它,但如果有人知道最初问题的答案,我会留下问题。

4

1 回答 1

1

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

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

于 2013-07-05T17:52:47.527 回答