Results 1 to 17 of 17

Thread: Drawing grids efficiently in QGraphicsScene

  1. #1
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Drawing grids efficiently in QGraphicsScene

    Hi,
    I need to draw grids in my app. The problem now is performance. The components move jerkily after adding grids. I confirmed from the profiler that scene::drawBackground() was most cpu consuming method.
    Can anyone please help me out ? Is there any techinique like caching or something ?
    Here is my code
    Qt Code:
    1. void SchematicScene::drawBackground(QPainter *p, const QRectF& crect)
    2. {
    3. const QRectF rect = crect.normalized();
    4. p->save();
    5. p->setPen(QPen(Qt::lightGray,1));
    6. int l = int(rect.left());
    7. l -= (l % 10);
    8.  
    9. int r = int(rect.right());
    10. r -= (r % 10);
    11. if(r < int(rect.right()))
    12. r += 10;
    13.  
    14. int t = int(rect.top());
    15. t -= (t % 10);
    16.  
    17. int b = int(rect.bottom());
    18. b -= (b % 10);
    19. if(b < int(rect.bottom()))
    20. b += 10;
    21.  
    22. for( int x = l; x <= r; x+=10)
    23. for( int y = t; y <= b; y+=10)
    24. p->drawPoint(x,y);
    25.  
    26. p->restore();
    27. }
    To copy to clipboard, switch view to plain text mode 
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Drawing grids efficiently in QGraphicsScene

    You can always make the grid "lighter" by reducing a number of points drawn.

  3. #3
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Quote Originally Posted by wysota View Post
    You can always make the grid "lighter" by reducing a number of points drawn.
    Hey thats a good tip and it did improve the performance when I made grid spacing 20 instead of 10 . But I guess 10px spacing grid is neccessary for my app.

    I found the documentation for QGraphicsView::CacheBackground and that showed good improvement even for grid spacing of 10px. But that dirties the grid when I scroll the view What can I do about this ?
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Drawing grids efficiently in QGraphicsScene

    What if you implemented the grid by placing points as QGraphicsItems instead of using drawBackground() ? This should speed up the rendering provided that only a part of the scene is visible at once.

  5. #5
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Quote Originally Posted by wysota View Post
    What if you implemented the grid by placing points as QGraphicsItems instead of using drawBackground() ? This should speed up the rendering provided that only a part of the scene is visible at once.
    This surely is good thinking in different direction. But will that be applicable to my case ?
    This is because the view is resizable and the user can easily resize according to him and I resize scene if the view is larger than scene. In that case the scene rect can be more than 1024*800 which means more than 8000 point items. And this is not maximum!
    Do you think its really worth a try in such cases ? Doesn't this lead to explosion in memory usage ??
    Last edited by Gopala Krishna; 11th February 2007 at 19:05. Reason: updated contents
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  6. #6
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    Using a cosmetic 0-width pen avoids unnecessary tesselation, calling QPainter::drawLines() is usually faster than QPainter::drawLine(), and using QGraphicsScene::drawBackground() is almost always faster than creating items. Here's an example that performs pretty well for me:

    Qt Code:
    1. class GridScene : public QGraphicsScene
    2. {
    3. public:
    4. GridScene(qreal x, qreal y, qreal w, qreal h)
    5. : QGraphicsScene(x, y, w, h)
    6. { }
    7.  
    8. protected:
    9. void drawBackground(QPainter *painter, const QRectF &rect)
    10. {
    11. const int gridSize = 25;
    12.  
    13. qreal left = int(rect.left()) - (int(rect.left()) % gridSize);
    14. qreal top = int(rect.top()) - (int(rect.top()) % gridSize);
    15.  
    16. QVarLengthArray<QLineF, 100> lines;
    17.  
    18. for (qreal x = left; x < rect.right(); x += gridSize)
    19. lines.append(QLineF(x, rect.top(), x, rect.bottom()));
    20. for (qreal y = top; y < rect.bottom(); y += gridSize)
    21. lines.append(QLineF(rect.left(), y, rect.right(), y));
    22.  
    23. qDebug() << lines.size();
    24.  
    25. painter->drawLines(lines.data(), lines.size());
    26. }
    27. };
    28.  
    29. int main(int argc, char **argv)
    30. {
    31. QApplication app(argc, argv);
    32.  
    33. GridScene scene(-1000, -1000, 2000, 2000);
    34. QGraphicsView view(&scene);
    35. view.rotate(33);
    36. view.show();
    37.  
    38. return app.exec();
    39. }
    To copy to clipboard, switch view to plain text mode 

    Notice the use of QVarLengthArray, that's a trick to avoid allocating memory. As long as no more than 100 grid lines are visible at the same time, it'll use the stack and nothing else. You can play with the size; a QLineF uses 32 bytes of memory so 100 of those means 3200 bytes of stack space; there's room for more.
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  7. The following 2 users say thank you to Bitto for this useful post:

    Gopala Krishna (11th February 2007), sarbh20ss (30th November 2013)

  8. #7
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    ...or drawPoints() instead of drawPoint(). ;-)
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  9. #8
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Thanks Bitto, I can see the performance difference.
    But when I move some 10 items together , the performance really comes down a lot. And now the profile shows Node::boundingRect() as culprit. I'll try to find out more and post it later.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  10. #9
    Join Date
    May 2006
    Location
    Bangalore,India
    Posts
    235
    Thanks
    7
    Thanked 25 Times in 24 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    Hi Gopala,
    Finally which method you used to draw grid and increase the performance?


  11. #10
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Hi rajesh,
    I couldn't improve the performance. I posted a new thread with example.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  12. #11
    Join Date
    May 2006
    Location
    Bangalore,India
    Posts
    235
    Thanks
    7
    Thanked 25 Times in 24 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    In your main function just add

    view->setViewport(new QGLWidget);

    I am sure, this will improve the performence.
    please add QGLWidget include file & path in settings.

  13. #12
    Join Date
    May 2006
    Location
    Bangalore,India
    Posts
    235
    Thanks
    7
    Thanked 25 Times in 24 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Windows

    Unhappy Re: Drawing grids efficiently in QGraphicsScene

    Hi Gopala,

    I copied your drawBackground(...) code,
    it displaying grid in scene, but later if I increase scene Rect then grid not increase to whole area.
    eg:
    m_scene->setSceneRect(0, 0, width, height);

    what to do? any idea?

    Thanks & Regards
    Rajesh

  14. #13
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Quote Originally Posted by rajesh View Post
    Hi Gopala,

    I copied your drawBackground(...) code,
    it displaying grid in scene, but later if I increase scene Rect then grid not increase to whole area.
    eg:
    m_scene->setSceneRect(0, 0, width, height);

    what to do? any idea?

    Thanks & Regards
    Rajesh
    Its working fine for me. I just added a slot to the scene which randomly increases size of scene and connected it QTimer. Whenever the sceneRect changed the view was properly updated for me.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  15. #14
    Join Date
    Jul 2006
    Posts
    126
    Thanks
    17
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    I have this code in my app:

    Qt Code:
    1. void KonstructorScene::createGrid(){
    2. QPoint rowStart(0, 0);
    3.  
    4. for(int j=0;j<m_grid.count();j++) qDeleteAll(m_grid[j]);
    5. m_grid.clear();
    6.  
    7. for(int i=0;i<m_size.height();i++){
    8. QPoint position(rowStart);
    9. QVector<SquareItem*> row;
    10.  
    11. for(int j=0;j<m_size.width();j++){
    12. SquareItem *square=new SquareItem(m_matrixTemplate[i][j], i, j, position);
    13.  
    14. row<<square;
    15. addItem(square);
    16. position+=QPoint(SQUARE_WIDTH/2, SQUARE_HEIGHT/2);
    17. }
    18. rowStart+=QPoint(-SQUARE_WIDTH/2, SQUARE_HEIGHT/2);
    19.  
    20. m_grid<<row;
    21. }
    22. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. void SquareItem::createPolygon(QPoint &position){
    2. QPolygon polygon;
    3.  
    4. updateColor();
    5. setPen(QPen(SQUARE_PEN_COLOR, PenSize));
    6. m_center=position;
    7. m_left=QPoint(position.x()-SQUARE_WIDTH/2, position.y());
    8. m_top=QPoint(position.x(), position.y()-SQUARE_HEIGHT/2);
    9. polygon<<m_left<<m_top
    10. <<QPoint(position.x()+SQUARE_WIDTH/2, position.y())
    11. <<QPoint(position.x(), position.y()+SQUARE_HEIGHT/2);
    12.  
    13.  
    14. setPolygon(polygon);
    15. }
    To copy to clipboard, switch view to plain text mode 

  16. #15
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Drawing grids efficiently in QGraphicsScene

    Quote Originally Posted by xgoan View Post
    I have this code in my app:
    ...
    You mean use square items as grid right ? I'll try but if you don't mind can you show the declaration of variables used and prototype of constructor for SquareItem.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  17. #16
    Join Date
    Jul 2007
    Posts
    39
    Thanks
    10

    Default Re: Drawing grids efficiently in QGraphicsScene

    Hi

    Did you find an efficient way to draw the grid?

    I am running into the same issue too? My grid is very slow. Also when I zoomIn or zoomOut, I have many wide irregular gaps between grids.

    Thanks
    Arjun

  18. #17
    Join Date
    Jun 2012
    Posts
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Drawing grids efficiently in QGraphicsScene

    Hello, I know this thread is so old, but I think I can contribute. Recently I had to do something similar and I got the same problem, eficiency, I develop a simple solution with a simple technique that uses a bitmap to draw all, is so fast and efficient, the explanation is in my website Creación de grilla de forma eficiente en QGraphicsView/QGraphicsScene but is spanish, if you think that you can exploit this, then visit it.

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.