PDA

View Full Version : Slow painting in QGraphicsView



JonathanForQT4
11th July 2007, 10:25
Hello all,

in the program when I am painting some specific objects to the QGraphicsScene it goes very slowly....this only happens when I am painting text.

I paint the text using a QPainterPath and then adding the text to the QPainterPath.

I think in this specific example the painting of everything is so slow because the QPainterPath's which print the text overlap.

So, my question is....does anyone know that if the QPainterPaths overlap, is there any know effects which cause everything to slow down?

Thanks,

Jonathan

jpn
11th July 2007, 10:54
Drawing a painter path in general is a complex operation. Perhaps you could draw the painter path once on a pixmap and then draw the pixmap on the screen?

JonathanForQT4
11th July 2007, 14:06
how would this work...the pixmap would get painted over the scene? The names are in objects that need to be selectable and need to receive mouseevents, I'm assuming that if the name is a pixmap that if you clicked on the rectangle (bounds) of the name the object wouldn't receive a command....unfortunately this won't fly :(

Is there any way to make the drawPath more efficient?

Gopala Krishna
11th July 2007, 14:29
Are you experiencing this slow down only while moving the objects or do you experience even when it just gets painted (hide/show, maximize view) ?
If it is due to the former reason and if you are using Qt-4.3 ,then you can perhaps try
view->setViewportUpdateMode(QGraphicsView::SmartViewport Update);
This updates the union of intersecting rects rather than only the regions which improves the speed when there are lots of intersections.

JonathanForQT4
12th July 2007, 13:52
Gopala Krishna: I just updated from 4.2.3 to 4.3 in the hopes that this would solve the problem....no dice...but the program works fast than with 4.2.3 so thanks for indirectly getting me to upgrade....I find the fastest (with everything working) setting is QGraphicsView::MinimalViewportUpdate :)

I still think it has to do with text printing over other text. Please let me know if there is something I can do with the QPath boundaries to help improve this...

Thanks for the reply Gopala Krishna

Cheers,

Jonathan

jpn
12th July 2007, 13:58
I still think it has to do with text printing over other text.
Remember that you're not drawing text but actually an extremely complex set of curves. Why could you not dump the QPainterPath to a QPixmap and use QGraphicsPixmapItem instead of QGraphicsPathItem?

fullmetalcoder
12th July 2007, 13:59
You might also be interested in changing the Optimization Flags (http://doc.trolltech.com/4.3/qgraphicsview.html#optimizationFlags-prop) and the Cache Mode (http://doc.trolltech.com/4.3/qgraphicsview.html#cacheMode-prop)...

Gopala Krishna
12th July 2007, 14:20
Gopala Krishna: I just updated from 4.2.3 to 4.3 in the hopes that this would solve the problem....no dice...but the program works fast than with 4.2.3 so thanks for indirectly getting me to upgrade....I find the fastest (with everything working) setting is QGraphicsView::MinimalViewportUpdate :)


You are welcome :)

BTW can you provide a screenshot of your app ?

JonathanForQT4
12th July 2007, 15:41
thanks for all the replies guys...

as of now I'm just using the painter within void paint method within the reimplemented QGraphicsItem to paint the path.....so the path itself isn't an item...which could be why it laggs so much...

so I'm going to try and pass the scene in and make an item and add it to the scene...I'll let you guys know how it goes :P

:)

Gopala Krishna: will provide a screen shot of the app tomorrow when I have a chance :)

cheers,

Jonathan

JonathanForQT4
13th July 2007, 13:12
ok, I tried doing the whole dumping the path to the qpixmap.....I have a feeling I'm doing it wrong.

QPixmap something;
QRect tester((int)myPath.boundingRect().topLeft().x(), (int)myPath.boundingRect().topLeft().y(), (int)myPath.boundingRect().width(), (int)myPath.boundingRect().height());
something.copy(tester);
QGraphicsPixmapItem *test = new QGraphicsPixmapItem(something);
m_parentScene->addItem(test);

I'm sure this is wrong, as I don't see any text being printed anywhere..but if you could enlighten me as to how to "dump" the path into the pixmap, I would be very happy :D


Gopala Krishna, attached is a picture of my program. Some stuff has been edited out...

jpn
13th July 2007, 13:34
if you could enlighten me as to how to "dump" the path into the pixmap, I would be very happy :D


Create a large enough QPixmap
create a QPainter on the pixmap
paint the path with QPainter::drawPath()

Example:


QPixmap something(myPath.boundingRect().size().toSize());
QPainter painter(&something);
painter.translate(-myPath.boundingRect().topLeft());
painter.drawPath(myPath);
painter.end();
QGraphicsPixmapItem *test = new QGraphicsPixmapItem(something);
m_parentScene->addItem(test);

Hope this clears it out :)

Bitto
15th July 2007, 11:08
Just a remark; a classic performance hit when drawing text using QPainterPath is to set the painter pen, or rely on the painter's default pen, forcing QPainter to render the text outline. The outline is extremely complex for text, and in most cases you don't want it - instead you just want to fill the text; i.e., set the brush and disable the pen. So:



QPainterPath path;
path.addText("Ladada");

QPainter painter(...);
painter.drawPath(path); // <- slow! draws the outline with the default pen set

painter.setPen(Qt::NoPen);
painter.setBrush(Qt::black);
painter.drawPath(path); // <- fast!

JonathanForQT4
16th July 2007, 09:54
ok, so I've tried jpn and bitto's methods, jpn's doesn't really give me a performance increase, but bitto's does :) It's faster, but still noticably slower than all other examples...only when you first zoom in -- so only that text is visible in the viewport, does it really speed up to "normal" speed...(like all other examples). I still think this has to do with caching etc....is there a way to further optimize this? I can't seem to believe that this is as good as it gets :-|

There a way to only display the mypath if it's going to be displayed large than X rect in the viewport or something? I can't think of anything else, since I've already tried the view->setViewportUpdateMode(All different modes :P);