QGraphicsView performance [solved]
I'm trying to write a relatively simple visualization using QGraphicsView. Basically, I have 1000 or so filled ellipses on my QGraphicsView. Several times each second, I want to change the colors of some of them from blue to red and vice versa.
Right now, I'm doing something like this:
// loop over all the ellipses
QBrush brush = x ? red : blue;
With 1000 ellipses, this is slow. I can't update the colors more than once or twice per second. Does anyone have performance advice for me? There are plenty of results on google for the performance of QGraphicsView, but most of them seem to be concerned with writing custom QGraphicsItems.
Here are a couple of talks on QGraphicsView and performance from the Qt Dev. Days 2010
- "Qt GraphicsView in Depth":http://qt.nokia.com/developer/learning/online/talks/developerdays2010/tech-talks/qt-graphics-view-in-depth
- "Performance: Do Graphics the Right Way":http://qt.nokia.com/developer/learning/online/talks/developerdays2010/tech-talks/performance-do-graphics-the-right-way
You should refactor your code to only update the brushes on those items that actually need to be changed. Right now you are triggering an update of every single item.
Use caching of some sort. If you only have two colors of ellipse then I would make a custom QGraphicsItem that uses QPixmapCache to cache the items. Drawing an ellipse is quite an expensive operation. Blitting a pixmap is a lot cheaper. Using QPixmapCache as opposed to the built-in QGraphicsItem caching modes will allow you save a great deal of memory since the built-in methods use a separate pixmap for each item.
If some ellipses are always the same, then draw all of these as a single item rather than having one item per ellipse.
See how you get on with those suggestions. If it is still too slow then come back and we can try to help some more.
Thanks for the suggestions. Your first suggestion gave a slight performance improvement, but it wasn't huge because most of the items change every time anyway.
What helped more was a poor-man's version of your second and third suggestion: instead of creating one QGraphicsItem and switching brushes, I'm now creating QGraphicsItems of every color and switching between them using setVisible. This is much less memory-efficient than using a single cached QPixmap and it requires more start-up time (because Qt has to draw hundreds of identical ellipses), but it was easy to write and the performance is good enough for now.
Thanks for your help.