Results 1 to 12 of 12

Thread: QGraphicsScene is SLOW with a lot of items !

  1. #1
    Join Date
    Oct 2010
    Posts
    95
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Question QGraphicsScene is SLOW with a lot of items !

    Hi,

    I have a QGraphicScene with 200 items and it is very slow when scrolling or moving the items !!!!

    I setup my QGraphicsView this way :

    Qt Code:
    1. QNodesView::QNodesView(QWidget* parent)
    2. :QGraphicsView(parent), _zoomLevel(0), _zoomValue(1.0f)
    3. {
    4. setRenderHint(QPainter::Antialiasing, true);
    5.  
    6. setBackgroundBrush(QImage(":/pureStudio/Images/pgEditorBG.png"));
    7. setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    8.  
    9. // Multi-selection
    10. setDragMode(QGraphicsView::RubberBandDrag);
    11. // NoDrag, ScrollHandDrag, RubberBandDrag
    12.  
    13. // Optimization
    14. setOptimizationFlags(QGraphicsView::DontClipPainter);
    15. setOptimizationFlags(QGraphicsView::DontSavePainterState);
    16. setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing);
    17. setCacheMode(QGraphicsView::CacheBackground);
    18.  
    19. // Drag & drop
    20. setAcceptDrops(true);
    21. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: QGraphicsScene is SLOW with a lot of items !

    What kind of items are they? If you do a lot of zooming, background caching will not help you much. Try enabling item caching.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Oct 2010
    Posts
    95
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Exclamation Re: QGraphicsScene is SLOW with a lot of items !

    There are 2 kinds of items :
    - QGraphicsNode : a rectangular node, with a text
    - QGraphicsLink : it is a curve between the items, and an arrow

    It looks like theses :
    https://picasaweb.google.com/lh/phot...t=embedwebsite
    http://www.geeks3d.com/public/jegx/2...odebox2_03.jpg

    I have try with :
    Qt Code:
    1. setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    To copy to clipboard, switch view to plain text mode 

    But nothing helps !!! What is strange is that I'm able to display a 3D models with millions of faces, but not a 2D graphic with 700 items !
    Last edited by pl01; 4th August 2011 at 11:18.

  4. #4
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsScene is SLOW with a lot of items !

    What is strange is that I'm able to display a 3D models with millions of faces, but not a 2D graphic with 700 items !
    Why is that strange? QGraphicsFramework uses the CPU for its operations, while 3D displays use OpenGL or some other hardware-assisted mechanism. The graphics framework gives you a lot of canned functionality, but it comes at the cost of performance. If you need high performance, implement your own display routines using OpenGL; Qt provides support for such displays, but you'll have to roll a lot of your own supporting code.

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

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Quote Originally Posted by pl01 View Post
    There are 2 kinds of items :
    - QGraphicsNode : a rectangular node, with a text
    - QGraphicsLink : it is a curve between the items, and an arrow

    It looks like theses :
    https://picasaweb.google.com/lh/phot...t=embedwebsite
    http://www.geeks3d.com/public/jegx/2...odebox2_03.jpg
    I was rather asking whether they are pixmaps or regular items. If they are custom items, please post the implementation of boundingRect(), shape() and a piece of code showing how you create items.

    I have try with :
    Qt Code:
    1. setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    To copy to clipboard, switch view to plain text mode 

    But nothing helps !!!
    So there is completely no difference? What about ItemCoordinateCache?

    What is strange is that I'm able to display a 3D models with millions of faces, but not a 2D graphic with 700 items !
    Find the bottleneck and we'll deal with it. Or post a minimal compilable example reproducing the problem and we'll help you with finding the bottleneck.
    Last edited by wysota; 4th August 2011 at 12:55.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Oct 2010
    Posts
    95
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Thanks,

    I have try with setCacheMode(QGraphicsItem::ItemCoordinateCache); but sometimes it 'lock' my application !!! I have to restart it !!! In fact, sometimes it refresh but I have to wait for 40 seconds !!! It is the slowest mode !

    Also, I put the code for the 2 items :

    Qt Code:
    1. QGraphicsLink::QGraphicsLink(QGraphicsNode* output, int outLine, QGraphicsNode* input, int inLine)
    2. {
    3. setZValue(1.0f);
    4.  
    5. setFlags(ItemIsSelectable | ItemIsFocusable);
    6.  
    7. setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    8. //setCacheMode(QGraphicsItem::ItemCoordinateCache);
    9. }
    10.  
    11. QRectF QGraphicsLink::boundingRect() const
    12. {
    13. qreal extra = pen().width() * 0.5f + 60.f;
    14.  
    15. return QRectF(
    16. line().p1(),
    17. QSizeF(line().dx(), line().dy())
    18. ).normalized().adjusted(-extra, -extra, extra, extra);
    19. }
    20.  
    21. void QGraphicsLink::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0)
    22. {
    23. painter->setRenderHint(QPainter::Antialiasing, true);
    24.  
    25. //---- Choose the color
    26. int penWidth = 2;
    27. int arrowDelta = 11;
    28. QColor drawColor = Qt::black;
    29. if (OutputNode)
    30. {
    31. QConnector connector = OutputNode->GetOutputConnector(OutputConnectorIdx);
    32. if (connector.Type == PG_VNGEOMETRY)
    33. drawColor = PG_VNGEOMETRY_COLOR;
    34. else if (connector.Type == PG_VNCAMERA)
    35. drawColor = PG_VNCAMERA_COLOR;
    36. else if (connector.Type == PG_VNLIGHT)
    37. drawColor = PG_VNLIGHT_COLOR;
    38. else if (connector.Type == PG_VNMATERIAL)
    39. drawColor = PG_VNMATERIAL_COLOR;
    40. else if (connector.Type == PG_VNFILM)
    41. drawColor = PG_VNFILM_COLOR;
    42. else if (connector.Type == PG_VNINTEGRATOR)
    43. drawColor = PG_VNINTEGRATOR_COLOR;
    44.  
    45. else if (connector.Type == PG_MNSPECTRUM)
    46. drawColor = PG_MNSPECTRUM_COLOR;
    47. else if (connector.Type == PG_MNSPECTRALFUNCTION)
    48. drawColor = PG_MNSPECTRALFUNCTION_COLOR;
    49. else if (connector.Type == PG_MNFLOAT)
    50. drawColor = PG_MNFLOAT_COLOR;
    51. else if (connector.Type == PG_MNFRESNEL)
    52. drawColor = PG_MNFRESNEL_COLOR;
    53. else if (connector.Type == PG_MNMICROFACETDISTRIBUTION)
    54. drawColor = PG_MNMICROFACETDISTRIBUTION_COLOR;
    55. }
    56. else
    57. {
    58. drawColor = QColor(220, 220, 220);
    59. arrowDelta = 5;
    60. }
    61.  
    62. if (isSelected())
    63. {
    64. drawColor = QColor(220, 220, 220);
    65. penWidth = 4;
    66. }
    67.  
    68. //---- Curve
    69.  
    70. if (line().y1() < line().y2())
    71. {
    72. path.moveTo(line().x1(), line().y1());
    73. float deltaX = 0.25f * (line().x2() - line().x1());
    74. float deltaY = 0.25f * (line().y2() - line().y1());
    75.  
    76. path.cubicTo(
    77. line().x1(), line().y1() + 3 * 14,
    78. line().x1() + 4 * deltaX, line().y1() + 1 * 14,
    79. line().x2(), line().y2() - 14);
    80. }
    81. else
    82. {
    83. path.moveTo(line().x1(), line().y1());
    84. float deltaX = 0.25f * (line().x2() - line().x1());
    85. float deltaY = 0.25f * (line().y2() - line().y1());
    86.  
    87. path.cubicTo(
    88. line().x1() + 40, line().y1() + 40,
    89. line().x2() - 40 , line().y2() - 40 - 14,
    90. line().x2(), line().y2() - 14);
    91. }
    92.  
    93. painter->setPen(QPen(drawColor, penWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    94. painter->drawPath(path);
    95.  
    96. //---- Arrow
    97. //Draw an arrow-head shaped path at the end of the line's path
    98. QPainterPath arrowHead;
    99. arrowHead.setFillRule(Qt::WindingFill);
    100.  
    101. //-- Bottom arrow
    102. QPointF pos;
    103. arrowHead.moveTo(QPointF(-4, -5));
    104. arrowHead.lineTo(QPointF(0, 5));
    105. arrowHead.lineTo(QPointF(4, -5));
    106. arrowHead.lineTo(QPointF(-4, -5));
    107.  
    108. QMatrix mat;
    109. mat.translate(line().p2().x(), line().p2().y() - arrowDelta);
    110. arrowHead = mat.map(arrowHead);
    111.  
    112. // Create a graphics path item based on this path
    113. painter->setBrush(drawColor);
    114. painter->drawPath(arrowHead);
    115. }
    116.  
    117. QPainterPath QGraphicsLink::shape() const
    118. {
    119. //---- Curve
    120.  
    121. if (line().y1() < line().y2())
    122. {
    123. path.moveTo(line().x1(), line().y1());
    124. float deltaX = 0.25f * (line().x2() - line().x1());
    125. float deltaY = 0.25f * (line().y2() - line().y1());
    126.  
    127. path.cubicTo(
    128. line().x1(), line().y1() + 3 * 14,
    129. line().x1() + 4 * deltaX, line().y1() + 1 * 14,
    130. line().x2(), line().y2() - 14);
    131. }
    132. else
    133. {
    134. path.moveTo(line().x1(), line().y1());
    135. float deltaX = 0.25f * (line().x2() - line().x1());
    136. float deltaY = 0.25f * (line().y2() - line().y1());
    137.  
    138. path.cubicTo(
    139. line().x1() + 40, line().y1() + 40,
    140. line().x2() - 40 , line().y2() - 40 - 14,
    141. line().x2(), line().y2() - 14);
    142. }
    143.  
    144. //---- Arrow
    145. path.setFillRule(Qt::WindingFill);
    146. QPointF pos;
    147. path.moveTo(QPointF(-4, -5));
    148. path.lineTo(QPointF(0, 5));
    149. path.lineTo(QPointF(4, -5));
    150. path.lineTo(QPointF(-4, -5));
    151.  
    152. QMatrix mat;
    153. mat.translate(line().p2().x(), line().p2().y() - 11);
    154. path = mat.map(path);
    155.  
    156. return ShapeFromPath(path, QPen(QColor(), 6));
    157. }
    158.  
    159. QPainterPath QGraphicsLink::ShapeFromPath(const QPainterPath &path, const QPen &pen)
    160. {
    161. // We unfortunately need this hack as QPainterPathStroker will set a width of 1.0
    162. // if we pass a value of 0.0 to QPainterPathStroker::setWidth()
    163. const qreal penWidthZero = qreal(0.00000001);
    164.  
    165. if (path == QPainterPath())
    166. return path;
    167. ps.setCapStyle(pen.capStyle());
    168. if (pen.widthF() <= 0.f)
    169. ps.setWidth(penWidthZero);
    170. else
    171. ps.setWidth(pen.widthF());
    172. ps.setJoinStyle(pen.joinStyle());
    173. ps.setMiterLimit(pen.miterLimit());
    174. QPainterPath p = ps.createStroke(path);
    175. p.addPath(path);
    176. return p;
    177. }
    To copy to clipboard, switch view to plain text mode 



    Qt Code:
    1. QGraphicsNode::QGraphicsNode(QNodesScene* qscene)
    2. {
    3. static int count = 0;
    4. setObjectName( QString("object%1").arg(count++) );
    5. setRect(-QGraphicsNodeWidth, -QGraphicsNodeHeight, QGraphicsNodeWidth, QGraphicsNodeHeight);
    6.  
    7. qscene->addItem(this);
    8. qscene->AddQGraphicsNode(this);
    9. setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable | ItemSendsScenePositionChanges);
    10.  
    11. setCacheMode(QGraphicsItem::DeviceCoordinateCache);
    12. //setCacheMode(QGraphicsItem::ItemCoordinateCache);
    13.  
    14. setZValue(2.0f);
    15. }
    16.  
    17. void QGraphicsNode::initializeBackground(QLinearGradient& gradient)
    18. {
    19. gradient.setColorAt(0.0f, QColor(60,60,60,255));
    20. gradient.setColorAt(0.3f, QColor(30,30,30,255));
    21. gradient.setColorAt(0.31f, QColor(20,20,20,255));
    22. gradient.setColorAt(1.0f, QColor(20,20,20,255));
    23. }
    24.  
    25. void QGraphicsNode::paint(QPainter* p, const QStyleOptionGraphicsItem* opt, QWidget* w)
    26. {
    27. Q_UNUSED(w)
    28.  
    29. if (HasSubTitle())
    30. setRect(-QGraphicsNodeWidth, -QGraphicsNodeHeight, QGraphicsNodeWidth, QGraphicsNodeHeight + 20);
    31.  
    32. //---- Draw the background
    33. QLinearGradient grad(rect().topLeft(), rect().bottomLeft());
    34. if(isSelected())
    35. {
    36. grad.setColorAt(0.0f, QColor(150,60,60,255));
    37. grad.setColorAt(0.3f, QColor(120,30,30,255));
    38. grad.setColorAt(0.31f, QColor(110,20,20,255));
    39. grad.setColorAt(1.0f, QColor(110,20,20,255));
    40. }
    41. else
    42. initializeBackground(grad);
    43.  
    44. p->fillRect(rect(), grad);
    45. p->drawRect(rect());
    46.  
    47. //---- Draw the input connectors
    48. for(int i = 0; i < GetInputConnectorCount(); i++)
    49. {
    50. int connectorType = GetInputConnector(i).Type;
    51. QRectF ir = GetInputConnectorRect(i);
    52.  
    53. if (connectorType == PG_VNGEOMETRY)
    54. p->fillRect(ir, PG_VNGEOMETRY_COLOR);
    55. else if (connectorType == PG_VNCAMERA)
    56. p->fillRect(ir, PG_VNCAMERA_COLOR);
    57. else if (connectorType == PG_VNLIGHT)
    58. p->fillRect(ir, PG_VNLIGHT_COLOR);
    59. else if (connectorType == PG_VNMATERIAL)
    60. p->fillRect(ir, PG_VNMATERIAL_COLOR);
    61. else if (connectorType == PG_VNFILM)
    62. p->fillRect(ir, PG_VNFILM_COLOR);
    63. else if (connectorType == PG_VNINTEGRATOR)
    64. p->fillRect(ir, PG_VNINTEGRATOR_COLOR);
    65.  
    66. p->drawRect(ir);
    67. }
    68.  
    69. //---- Draw the output connectors
    70. for(int i = 0; i < GetOutputConnectorCount(); i++)
    71. {
    72. int connectorType = GetOutputConnector(i).Type;
    73. QRectF or = GetOutputConnectorRect(i);
    74.  
    75. if (connectorType == PG_VNGEOMETRY)
    76. p->fillRect(or, PG_VNGEOMETRY_COLOR);
    77. else if (connectorType == PG_VNCAMERA)
    78. p->fillRect(or, PG_VNCAMERA_COLOR);
    79. else if (connectorType == PG_VNLIGHT)
    80. p->fillRect(or, PG_VNLIGHT_COLOR);
    81. else if (connectorType == PG_VNMATERIAL)
    82. p->fillRect(or, PG_VNMATERIAL_COLOR);
    83. else if (connectorType == PG_VNFILM)
    84. p->fillRect(or, PG_VNFILM_COLOR);
    85. else if (connectorType == PG_VNINTEGRATOR)
    86. p->fillRect(or, PG_VNINTEGRATOR_COLOR);
    87.  
    88. else if (connectorType == PG_MNSPECTRUM)
    89. p->fillRect(or, PG_MNSPECTRUM_COLOR);
    90. else if (connectorType == PG_MNSPECTRALFUNCTION)
    91. p->fillRect(or, PG_MNSPECTRALFUNCTION_COLOR);
    92. else if (connectorType == PG_MNFLOAT)
    93. p->fillRect(or, PG_MNFLOAT_COLOR);
    94. else if (connectorType == PG_MNFRESNEL)
    95. p->fillRect(or, PG_MNFRESNEL_COLOR);
    96. else if (connectorType == PG_MNMICROFACETDISTRIBUTION)
    97. p->fillRect(or, PG_MNMICROFACETDISTRIBUTION_COLOR);
    98.  
    99. p->drawRect(or);
    100. }
    101.  
    102. //---- Name
    103. QString nodeName = GetName();
    104.  
    105. QRectF nameRect(rect().left(), rect().top(), rect().width(), 25);
    106. QFont font(p->font());
    107. font.setWeight(QFont::DemiBold);
    108. p->setFont(font);
    109. p->setPen(Qt::white);
    110. p->drawText(nameRect, Qt::AlignCenter, nodeName);
    111.  
    112. //---- Sub title
    113. if (!HasSubTitle())
    114. return;
    115.  
    116. QRectF subTitleRect(rect().left(), rect().top() + 20, rect().width(), 25);
    117. font.setWeight(QFont::Light);
    118. p->setFont(font);
    119. p->drawText(subTitleRect, Qt::AlignCenter, GetSubTitle());
    120. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Mar 2011
    Posts
    63
    Thanks
    11
    Thanked 5 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsScene is SLOW with a lot of items !

    For optimizing your QGraphicsView and QGraphicsScene take a look at these two links. They helped me alot.

    http://agurines.blogspot.com/2011/02...l#comment-form

    http://qt.nokia.com/learning/online/...-view-in-depth

  8. #8
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Yuor code is not DRY!
    There is QGraphicsPathItem (set no brush update path when positions of connected node changes). This class should be written in best possible way. You can subclass it to save time and performance.

    IMHO your items can be build easily with ready items and this should give better results.

  9. #9
    Join Date
    Oct 2010
    Posts
    95
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Thanks MarekR22,

    But what (and how ??) "set no brush update path when positions of connected node changes" ?

    Even, I have completely put in comment the "paint" method from the "link" graphic-item but it is still slow !!! :-( :-(
    Last edited by pl01; 5th August 2011 at 11:45.

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

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Your boundingRect() and shape() implementations are suboptimal. There is no point in recalculating those values each time the method is called. If something makes your application freeze then apparently something in your code is invalid. Implementation of paint() is also suboptimal although this is a secondary issue if you are using item cache.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Oct 2010
    Posts
    95
    Thanks
    2
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Ok,

    but how can I do ? is there a way to know that I have to recompute theses values ? Which method/event should I use ?

    Thx

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

    Default Re: QGraphicsScene is SLOW with a lot of items !

    Quote Originally Posted by pl01 View Post
    is there a way to know that I have to recompute theses values ?
    You are in control of your item. If you do something that changes either the bounding rect or the shape (usually both) and you call prepareGeometryChange() then you have to recalculate those values.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. How to add items in a QGraphicsScene?
    By schmimona in forum Qt Programming
    Replies: 2
    Last Post: 3rd August 2011, 08:53
  2. Select all items in QTreeView. Why very slow ?
    By MaxBooster in forum Qt Programming
    Replies: 0
    Last Post: 25th August 2010, 06:12
  3. QGraphicsScene: selection of multiple items is very slow
    By felixrubio in forum Qt Programming
    Replies: 0
    Last Post: 22nd July 2010, 15:51
  4. QGraphicsScene too slow
    By samsam in forum Qt Programming
    Replies: 1
    Last Post: 10th July 2009, 16:18
  5. Too slow adding & defining items to QTreeWidget
    By jnk5y in forum Qt Programming
    Replies: 16
    Last Post: 22nd April 2008, 20:26

Tags for this Thread

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.