[PyQt] Pixel pushing performance
Aaron Digulla
digulla at hepe.com
Thu May 8 08:39:45 BST 2008
Quoting Håkon Bertheussen <haakon at bertheussen.com>:
> Hi,
>
> I'm just getting started with PyQt, trying to implement a fairly complex
> widget in python. Unfortunately, it cannot easily be painted using
> higher level drawing primitives, meaning that I have to set individual
> pixels. I realize that this obviously has a lot of overhead compared to
> a C++ implementation, but if possible I'd like to stay in Python. Here's
> what I'm doing now:
>
> 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?
1. Create the image outside of paintEvent and just use it in
paintEvent to draw the widget.
2. Use a background thread to fill the image
This way, it's still slow but the user won't be blocked in her work.
Also, have a look at NumPy. That allows you to treat the image as a
large array of int's which you can access directly. That's much faster
than calling setPixel().
After the image is complete, use one of the supplied methods to turn
the int's into pixels in one go. Still, you should consider drawing
the image somewhere else and just show it in paintEvent, especially if
the content doesn't change every time the user moves the window.
Regards,
--
Aaron "Optimizer" Digulla a.k.a. Philmann Dark
"It's not the universe that's limited, it's our imagination.
Follow me and I'll show you something beyond the limits."
http://www.pdark.de/
More information about the PyQt
mailing list