Results 1 to 6 of 6

Thread: Showing QGraphicsEllipseItems extremely slow

  1. #1
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Showing QGraphicsEllipseItems extremely slow

    Hi,

    I have an application showing thousand of items (lines, points, polygons).
    the user can click a button to show/hide all those items.

    I'm porting that application from Qt3 to Qt4 (4.5.1).
    The application was working greatily in Qt3, but after porting it to Qt4 I'm noticing it is extremely slower showing and hiding items. Debugging it deeply I found out that the bottleneck is the showing of points (QGraphicsEllipseItems) that is causing the application to get stuck. Actually to show 10000 points (QGraphicsEllipseItems w = 4 and h = 4) it took more that 5 minutes while in Qt3 it was almost instantaneous.
    The same amount of Lines and Polygons is shown quite fast (just a few seconds).

    I disabled the indexing in QGraphicsScene just to avoid it was causing the slowness, but it seems it didn't cause any improvement.

    Am I missing something?
    Here is part of the code I'm using to create and show the items. Attache is the whole Qt project.


    Qt Code:
    1. MainWindow::MainWindow( QWidget * parent, Qt::WindowFlags flags)
    2. : QMainWindow(parent, flags)
    3. {
    4. ...
    5. scene = new QGraphicsScene(this);
    6. scene->setSceneRect(0, 0, 800, 600);
    7. scene->setItemIndexMethod(QGraphicsScene::NoIndex);
    8. scene->setBackgroundBrush(Qt::black);
    9. gvView->setScene(scene);
    10.  
    11. // create the items
    12. createNPoints(10000);
    13. }
    14.  
    15. /*
    16.  * create some points
    17.  */
    18. void MainWindow::createNPoints(int num)
    19. {
    20. for( int i = 0; i < num; i++ )
    21. createPoint();
    22. }
    23.  
    24. void MainWindow::createPoint()
    25. {
    26. QGraphicsEllipseItem *p = scene->addEllipse(qrand()%int(scene->width()),qrand()%int(scene->height()), 4, 4);
    27.  
    28. QColor c(qrand()%32*8,qrand()%32*8,qrand()%32*8);
    29. p->setPen(c);
    30. p->setBrush(c);
    31. p->setZValue(qrand()%256);
    32.  
    33. pointsList.append(p);
    34. }
    35.  
    36. /*
    37.  This is the slot called when the user clicks the button to show the items
    38. */
    39. void MainWindow::showPoints(bool yes)
    40. {
    41. for(int i = 0; i < pointsList.count(); i++)
    42. {
    43. if(yes)
    44. pointsList[i]->show();
    45. else
    46. pointsList[i]->hide();
    47. }
    48. }
    To copy to clipboard, switch view to plain text mode 


    Thanks in advance for your help.
    Attached Files Attached Files

  2. #2
    Join Date
    Dec 2009
    Posts
    128
    Thanks
    7
    Thanked 14 Times in 14 Posts
    Platforms
    Unix/X11 Windows

    Default Re: Showing QGraphicsEllipseItems extremely slow

    here is how i did :

    qgraphicsperformance project modified.zip

    certainly not elegant but sensibly faster

  3. The following user says thank you to totem for this useful post:

    kalos80 (12th January 2010)

  4. #3
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Showing QGraphicsEllipseItems extremely slow

    Totem,

    your solution works greatly! Now the show/hide of points is almost instantaneous.
    Do you know what is causing the slowness using the default ellipse paint?

    I think this is a very bad problem of QGraphicsScene, ellipses show/hide is unusable.

    thanks again

  5. #4
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Showing QGraphicsEllipseItems extremely slow

    Totem,

    I analysed better your solution.
    What you are doing is when items are hidden by the user avoid to draw them (you disable the drawing in the paintEvent), but actually items are still there.
    If you click the scene when items are hidden and you call items() on the scene, it will returns you some items under the mouse even if those items are hidden.

    Unfortunately this is not a behavior admitted in my application, ;(

  6. #5
    Join Date
    Dec 2009
    Posts
    128
    Thanks
    7
    Thanked 14 Times in 14 Posts
    Platforms
    Unix/X11 Windows

    Default Re: Showing QGraphicsEllipseItems extremely slow

    Sorry i didn't know selection was important in your app.
    Indeed what seems slow is to change items flags when there is a lot of items to affect, but I don't know why

    If you want to keep my solution, you could take a look at QGraphicsItem::itemChange() method, with the QGraphicsItem::ItemSelectedChange flag and disable change it when s_show is false. But this becomes more and more ugly :

    Qt Code:
    1. class MyEllipseItem : public QGraphicsEllipseItem
    2. {
    3. protected :
    4.  
    5. static bool s_show ;
    6.  
    7. public :
    8. MyEllipseItem( qreal x, qreal y, qreal w, qreal h )
    9. {
    10. setFlag( ItemIsSelectable, true ) ;
    11. }
    12.  
    13. static void setEllipsesVisible( bool v ) { s_show=v ; }
    14.  
    15. protected :
    16. virtual void paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    17. {
    18. if( s_show )
    19. QGraphicsEllipseItem::paint(painter,option,widget) ;
    20. }
    21. virtual QVariant itemChange( GraphicsItemChange change, const QVariant & value )
    22. {
    23. if (change == QGraphicsItem::ItemSelectedChange )
    24. {
    25. // value is the new state.
    26. bool newState = value.toBool() ;
    27. return QVariant( newState&&s_show ) ;
    28. }
    29. return QGraphicsItem::itemChange(change, value);
    30. }
    31. } ;
    To copy to clipboard, switch view to plain text mode 
    Last edited by totem; 12th January 2010 at 17:51.

  7. #6
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Showing QGraphicsEllipseItems extremely slow

    The Qt support replied to me:

    "You're getting stuck in the code that manages which part of the screen should be repainted. When the items are showed/hidden explicitely they will request an update in the view, passing either their bounding box (I think its the bounding box, it could also be the shape(), but that would only be worse). This rectangle will be added to the update region, a QRegion, in the view. Since you have 10000 unique rectangles you get something equivalent to:

    QRegion completeRegion;

    for (int i=0; i<10000; ++i)
    completeRegion += item[i].boundingRect();

    where for each round in the loop, the region gets increasingly complex and the += is more and more heavy.

    The fix is to update everything in one go, ignoring the update management. This can be done with:

    gvView->setViewportUpdateMode(QGraphicsView::FullViewport Update);
    "

    I tried that solution and it worked greatly

  8. The following user says thank you to kalos80 for this useful post:

    totem (13th January 2010)

Similar Threads

  1. Replies: 2
    Last Post: 17th September 2010, 17:38
  2. Image-based widgets showing is too slow in Qt 4.2.1
    By mkrentovskiy in forum Qt Programming
    Replies: 11
    Last Post: 8th August 2007, 23:20
  3. QProcess extremely slow on Windows?
    By Pepe in forum Qt Programming
    Replies: 2
    Last Post: 26th March 2007, 01:25
  4. QTextEdit extremely slow with links
    By elahav in forum Qt Programming
    Replies: 2
    Last Post: 25th May 2006, 19:00
  5. Qt interface running extremely slowly...
    By jazztpt in forum Qt Programming
    Replies: 1
    Last Post: 4th February 2006, 12:12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.