Qt-interest Archive, February 2007
Using GraphicsView Framework to Display a Large Number of GraphicsItems
Message 1 in thread
I'm using the GraphicsView framework to visualize a large number of
GraphicsItems (right now > 1000, but eventually could be millions). Qt
doesn't seem to handle these large number of items very gracefully and
is painfully slow when I want to scroll around in the scene.
Currently I use an un-optimal way of handling scene updates - I
calculate all the items positions in the scene myself and set the
positions manually. I could be having Qt calculate the positions
automatically and just do an update for the exposed region of the
screen. But I think this will only be a temporary fix because
eventually I'm going to have to be manually re-drawing thousands of
items in the newly exposed region anyway.
So my question is: can the graphics view framework reasonably handle
thousands (or tens/hundreds of thousands) items drawn on the screen?
I'm contemplating moving my whole display system away from the
GraphicsView framework and manually generating a raster that contains
everything I want to display on screen. However, if GraphicsView can
handle this then I'd like to stick with this method of display. Perhaps
what I'm doing is grossly inefficient - so how should I be approaching
displaying a large number of items in a scene? Any help is greatly
appreciated,
Chris Portka
--
[ signature omitted ]
Message 2 in thread
On Tue, Feb 20, Chris Portka wrote:
> I'm using the GraphicsView framework to visualize a large number of
> GraphicsItems (right now > 1000, but eventually could be millions). Qt
> doesn't seem to handle these large number of items very gracefully and
> is painfully slow when I want to scroll around in the scene.
>
Hm, in my mindmaps I usually have 1000-10000 items. Works pretty well,
even if I move many of the items simulanously. Though a major slowdown
happens if I use background images.
> Currently I use an un-optimal way of handling scene updates - I
> calculate all the items positions in the scene myself and set the
> positions manually. I could be having Qt calculate the positions
> automatically and just do an update for the exposed region of the
> screen. But I think this will only be a temporary fix because
> eventually I'm going to have to be manually re-drawing thousands of
> items in the newly exposed region anyway.
>
Maybe you can set the level of detail so that only visible parts are
rendered? Is everything changing all the time? Any structures which
could make rendering easier?
Uwe
--
[ signature omitted ]
Message 3 in thread
Uwe Drechsel (@vym) wrote:
> On Tue, Feb 20, Chris Portka wrote:
>
>> I'm using the GraphicsView framework to visualize a large number of
>> GraphicsItems (right now > 1000, but eventually could be millions). Qt
>> doesn't seem to handle these large number of items very gracefully and
>> is painfully slow when I want to scroll around in the scene.
>>
>
> Hm, in my mindmaps I usually have 1000-10000 items. Works pretty well,
> even if I move many of the items simulanously. Though a major slowdown
> happens if I use background images.
I don't use a background image, but I do color the background solid
black, doubt this should be an issue. I do overlay many (yes, many)
items on top of each other though. There are items displayed that make
up an entire "background" so every new item displayed is somehow
displayed on top of another item.
>
>> Currently I use an un-optimal way of handling scene updates - I
>> calculate all the items positions in the scene myself and set the
>> positions manually. I could be having Qt calculate the positions
>> automatically and just do an update for the exposed region of the
>> screen. But I think this will only be a temporary fix because
>> eventually I'm going to have to be manually re-drawing thousands of
>> items in the newly exposed region anyway.
>>
>
> Maybe you can set the level of detail so that only visible parts are
> rendered? Is everything changing all the time? Any structures which
> could make rendering easier?
How would I set the level of detail for pre-generated QGraphicItems?
I understand this generation of QGraphicsItems is slow, but once all of
them are generated I thought it was Qt's job to make sure "only visible
parts are rendered." My problem is that after I generate these items, I
still have significant slowness in scrolling around. Everything is not
changing all the time, just according to user input (scroll, zoom, show
me some new items, etc.). I am currently using quad-trees to determine
what items need to be rendered on the screen. If you know of any other
structure to making rendering easier/faster then let me know. Thanks,
Chris Portka
--
[ signature omitted ]
Message 4 in thread
On Tue, Feb 20, Chris Portka wrote:
> Uwe Drechsel (@vym) wrote:
> >On Tue, Feb 20, Chris Portka wrote:
> >
> >>I'm using the GraphicsView framework to visualize a large number of
> >>GraphicsItems (right now > 1000, but eventually could be millions). Qt
> >>doesn't seem to handle these large number of items very gracefully and
> >>is painfully slow when I want to scroll around in the scene.
> >>
> >
> >Hm, in my mindmaps I usually have 1000-10000 items. Works pretty well,
> >even if I move many of the items simulanously. Though a major slowdown
> >happens if I use background images.
>
> I don't use a background image, but I do color the background solid
> black, doubt this should be an issue. I do overlay many (yes, many)
> items on top of each other though. There are items displayed that make
> up an entire "background" so every new item displayed is somehow
> displayed on top of another item.
>
Hm, maybe QT has problems to build up its binary trees where the stuff
is then. Another idea: AntiAliasing makes stuff quite slow on my old
machine.
> How would I set the level of detail for pre-generated QGraphicItems?
> I understand this generation of QGraphicsItems is slow, but once all of
> them are generated I thought it was Qt's job to make sure "only visible
> parts are rendered." My problem is that after I generate these items, I
Yes, think so too.
Uwe
--
[ signature omitted ]
Message 5 in thread
Chris,
I ran into the same problem, especially if you items overlap. I wrote up
some of the tricks I did to improve things here:
http://thesmithfam.org/blog/2007/02/03/qt-improving-qgraphicsview-performance/
--Dave
Chris Portka wrote:
> I'm using the GraphicsView framework to visualize a large number of
> GraphicsItems (right now > 1000, but eventually could be millions).
> Qt doesn't seem to handle these large number of items very gracefully
> and is painfully slow when I want to scroll around in the scene.
>
> Currently I use an un-optimal way of handling scene updates - I
> calculate all the items positions in the scene myself and set the
> positions manually. I could be having Qt calculate the positions
> automatically and just do an update for the exposed region of the
> screen. But I think this will only be a temporary fix because
> eventually I'm going to have to be manually re-drawing thousands of
> items in the newly exposed region anyway.
>
> So my question is: can the graphics view framework reasonably handle
> thousands (or tens/hundreds of thousands) items drawn on the screen?
> I'm contemplating moving my whole display system away from the
> GraphicsView framework and manually generating a raster that contains
> everything I want to display on screen. However, if GraphicsView can
> handle this then I'd like to stick with this method of display.
> Perhaps what I'm doing is grossly inefficient - so how should I be
> approaching displaying a large number of items in a scene? Any help
> is greatly appreciated,
--
[ signature omitted ]
Message 6 in thread
On 2/20/07, Chris Portka <cportka@xxxxxxxxxxxxxxx> wrote:
> I'm using the GraphicsView framework to visualize a large number of
> GraphicsItems (right now > 1000, but eventually could be millions). Qt
> doesn't seem to handle these large number of items very gracefully and
> is painfully slow when I want to scroll around in the scene.
>
> Currently I use an un-optimal way of handling scene updates - I
> calculate all the items positions in the scene myself and set the
> positions manually. I could be having Qt calculate the positions
> automatically and just do an update for the exposed region of the
> screen. But I think this will only be a temporary fix because
> eventually I'm going to have to be manually re-drawing thousands of
> items in the newly exposed region anyway.
>
> So my question is: can the graphics view framework reasonably handle
> thousands (or tens/hundreds of thousands) items drawn on the screen?
> I'm contemplating moving my whole display system away from the
> GraphicsView framework and manually generating a raster that contains
> everything I want to display on screen. However, if GraphicsView can
> handle this then I'd like to stick with this method of display. Perhaps
> what I'm doing is grossly inefficient - so how should I be approaching
> displaying a large number of items in a scene? Any help is greatly
> appreciated,
>
> Chris Portka
I'm currently playing with QGraphicsView to see how it suits my OS
project. It seems that it works pretty well. I did a stall test that
create canvas with 250000 items, and it work quite well (you can see
source at http://bead.svn.sourceforge.net/viewvc/bead/beco/trunk/design/tests/BeadsRenderTest/).
Few things I've discovered:
1) It much faster to load and take much less memory, if similar
brushes are shared. In my test sharing brushes (I have 100 different
types) helps to reduce memory footprint roughly by half.
2) I have a thousands of items, but only a (relatively) small variety
of their types. So in my case caching the items improves performance
drastically, especially when render in non-trivial (i.e. with
gradients in my case). This simple code (from the test mentioned
above) makes stuff much more responsive:
void paint ( QPainter * painter, const QStyleOptionGraphicsItem *
option, QWidget * widget = 0 )
{
QPixmap *cachedPixmap = _cachedBeads[_style];
if (!cachedPixmap) {
cachedPixmap = new QPixmap(20,20);
cachedPixmap->fill(QColor(0,0,0,0));
QPainter cp(cachedPixmap);
cp.setRenderHint(QPainter::Antialiasing);
QGraphicsEllipseItem::paint(&cp,option,widget);
_cachedBeads.insert(_style,cachedPixmap);
}
painter->drawPixmap(0,0,*cachedPixmap);
}
--
[ signature omitted ]