# Fast draw wxPython OnPaint

I have the following 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)


I need to draw on my window a number of circles [0, 2000] every N milliseconds (50 in my example), where at each step these circles may update their location.

The method I wrote works (the circles are anti-aliased too) but it's quite slow. Is there a way to improve my solution?

• Why do you need to update so quickly? That's way faster than the eye can see. – Mike Driscoll Oct 24 '14 at 16:22
• @MikeDriscoll Actually if I don't keep the delay so low the animation results very slow (I can't say way). Also on my computer I need 0.005 seconds to update entities and about 0.05 seconds to DrawEntities, therefore 50 milliseconds is the lower bound (I can't go faster...). – Nick Oct 24 '14 at 16:29
• I can't find anything about speed gains for that widget. Drawing 2000 circles every 50 milliseconds sounds pretty extreme though. I don't think anyone will be able to see the drawing taking place at that speed. But you might try floatcanvas (wxpython.org/Phoenix/docs/html/lib.floatcanvas.html) or possibly wxPython's Cairo interface. – Mike Driscoll Oct 24 '14 at 18:01
• Have you tried using wx.BufferedPaintDC instead of wx.PaintDC? – RufusVS Dec 23 '14 at 19:30

Generally, the Python style is to indent by one tab, or four spaces. Functions and variables should be named in snake_case, and classes should be in PascalCase. See PEP8 for more style information.

You should also use docstrings to describe what your functions do. Here's an example of how docstrings are used.

def my_func( ... ):
"""
Describe what your function does and
it's arguments in this docstring.
"""
...


Other than that, your code looks pretty nice! Good work!