[PyQt] Pixel pushing performance

Matt Newell newellm at blur.com
Thu May 8 04:09:47 BST 2008


On Wednesday 07 May 2008 18:59:33 Roberto Alsina wrote:
> >
> >      def paintEvent(self, event):
> >          canvas = QtGui.QImage(event.rect().size(),
> >                                QtGui.QImage.Format_RGB32)
> >          for i in xrange(0, canvas.height()):
> >              for j in xrange(0, canvas.width()):
> >                  canvas.setPixel(j, i, 123456)
> >          painter = QtGui.QPainter()
> >          painter.begin(self)
> >          painter.fillRect(event.rect(), QtGui.QBrush(canvas))
> >          painter.end()
> >
> > Obviously, in my real application the inner statement in the loop is a
> > bit more complex, but even the above example is slow when the widget is
> > fairly large (e.g. 300x300px). Is there a way to speed this up?
>
> Try putting very little busywork in there instead of a setPixel (like,
> calculate a square root),and I bet that will slow enough to be noticeable,
> too.
>
> You need to find a way not to *have* to do that, or you will need to do it
> outside python. 300x300 are 90K iterations. 90K anything takes a little
> while.
>
>    

Yep, and even if you wrote the loop in C++ it would still be slow because 
setPixel is a non-inlined function.  It would probably be 10x-100x faster by 
doing pointer arithmetic and avoiding the function call, though none of that 
matters as long as the loop is in python.

Basically you have two choices
1) Avoid per-pixel drawing for real time updates, either by caching or drawing 
with primitives through the qpainter or opengl apis(, or numpy, but I don't 
know about that).
2) Use optimized lower level drawing code written in C/C++

Matt



More information about the PyQt mailing list