Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Gridlines and rendering performance



  • Hi,

    i added in a GVF application gridlines. I tried three options:

    1- Subclassing QGraphicsScene and implementing lines in drawBackground()
    2- Subclassing QGraphicsItem and implementing lines in paint()
    3- Adding QGraphicsLineItem's in a QGraphicsItemGroup and then adding the group item into the scene.

    The first two options were very slow. As i added a new QGraphicsItem in the scene and moved it, the item moved behind the mouse pointer. The third option was clearly faster than first two ones.

    I tried to change the rendering options of the view, but as soon as an item touched the grid, it became very slow.

    I would like to implement the first solution for a better sw-design.

    Any idea how can the rendering performance of the QGraphicsView be improved?



  • I am using the first option drawBackground() and I get very good performance for a drawing application. Could you post your code so that we could have a look and possibly suggest improvements?



  • Oh, i removed that function for performance issues. I m using the third one. But it was something like this:

    @
    ..
    m_space = 10;
    ..
    // Tried both QPen and setBackgroundBrush(Qt::blue);
    ...
    void MyScene::drawBackground(QPainter * painter, const QRectF & rect)
    {

    /* Draw lines */
    for (int x = 0; x <= 500; x += m_space)
    {
        painter->drawLine(x, 0, x, 500);
    }
    
    for (int y = 0; y <= 500; y += m_space)
    {
        painter->drawLine(0, y, 500, y);
    }
    

    }
    @

    And i have an item (inherited from QGraphicsObject), which has 3 rectangles and text in it (not complex).

    If i move my item on the grid, it becomes very slow (if FullViewportUpdate is set, then it is slow everywhere).

    i hope this code is enough, or else i can implement it again and send it (real code can not fit in here)

    Thanks.



  • OK. I can see that that might be slow (lots of drawLine calls)
    I
    Here's what I did - the difference is that all the lines are put into a variable length array, and then just one draw call.

    @
    void GraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
    {
    if (!m_gridOn)
    return;
    //this draws the background grid
    qreal left = int(rect.left()) - (int(rect.left()) % m_gridSize);
    qreal top = int(rect.top()) - (int(rect.top()) % m_gridSize);

    QVarLengthArray<QLineF, 100> lines;
    for (qreal x= left; x < rect.right(); x += m_gridSize)
    lines.append(QLineF(x, rect.top(), x, rect.bottom()));

    for (qreal y= top; y < rect.bottom(); y += m_gridSize)
    lines.append(QLineF(rect.left(), y, rect.right(), y));

    painter->setPen(m_gridPen);
    painter->drawLines(lines.data(), lines.size());
    }
    @



  • Ok, i took some time, changed my code and put your drawBackground()-version to test what happens => it was fast. That was amazing. Then i begin to play with your code. After a while i found out one thing : i wanted to define A4 page size for borderlines and therefore put a printer object in drawBackground() -> it was very slow again. Then i defined setBackgroundBrush() in this function, saw it was faster than using printer-object but slower as expectations. So if you define a printer object or call setBackgroundBrush() in drawBackground() it will be slow.

    But i dont think this was my problem yesterday, because i tried to draw lines with only QPen too and it was slow, which is fast now. I think there was another problem, but i can't reproduce it again now.

    After all this i can say i observed this :

    • drawing lines in loop doesn't make it slow : that is the answer to my question
    • using QPrinter makes drawBackground() very slow
    • using setBackgroundBrush() makes drawBackground() slow
    • using QPen is faster than using setBackgroundBrush()

    I dont know if these are general.

    Thank you for your support.


Log in to reply