改进wxPython的OnPaint

3 投票
2 回答
985 浏览
提问于 2025-04-29 11:49

我有一个这样的 wx.Window

class SketchWindow(wx.Window):

  def __init__(self, parent):
    wx.Window.__init__(self, parent, -1)
    self.SetBackgroundColour('White')
    # Window event binding
    self.Bind(wx.EVT_PAINT, self.OnPaint)
    self.Bind(wx.EVT_IDLE, self.OnIdle)
    # run
    self.Run()

  def OnPaint(self, evt):
    self.DrawEntities(wx.PaintDC(self))

  def DrawEntities(self, dc):
    dc.SetPen(wx.Pen('Black', 1, wx.SOLID))
    dc.SetBrush(wx.Brush('Green', wx.SOLID))
    # draw all
    for e in self.entities:
      x, y = e.location
      dc.DrawCircle(x, y, 4)

  def OnIdle(self, event):
    self.Refresh(False)

  def Run(self):
    # update self.entities ...
    # call this method again later
    wx.CallLater(50, self.Run)

我需要在我的窗口上每隔 N 毫秒(在我的例子中是 50 毫秒)画一些圆圈,数量在 0 到 2000 之间。在每次更新时,这些圆圈的位置可能会改变。

我写的方法是可以工作的(这些圆圈的边缘也很平滑),但速度有点慢。有没有办法让我的解决方案更快一些?

暂无标签

2 个回答

0

你应该更详细地解释一下,为什么你觉得这个代码运行得很慢。(这段代码看起来像是一个台球桌模拟的部分)。一些时间性能分析会对你有帮助。我为了让你的代码片段能够运行,添加了很多代码,但我有几个快速的观察:1)你可能需要在你的 OnPaint() 函数里加上 dc.Clear(),否则你会看到之前绘制的圆圈留下的“痕迹”。另外,你可以考虑使用一个缓冲区DC,这样可以让图形更新更流畅,方法是把

def OnPaint(self, evt):
    self.DrawEntities(wx.PaintDC(self))

改成

 def OnPaint(self, evt):
     self.DrawEntities(wx.BufferedPaintDC(self))
1

我觉得提高性能的基本思路是先在内存中进行绘制,然后再把结果显示到屏幕上。你可以使用BufferedCanvas来实现这个效果(链接页面底部有示例)。

撰写回答