2

I'm trying to draw a background grid in the drawBackground() function of my QGraphicsScene subclass:

void Scene::drawBackground(QPainter *painter, const QRectF &rect)
{
    const int gridSize = 50;

    const int realLeft = static_cast<int>(std::floor(rect.left()));
    const int realRight = static_cast<int>(std::ceil(rect.right()));
    const int realTop = static_cast<int>(std::floor(rect.top()));
    const int realBottom = static_cast<int>(std::ceil(rect.bottom()));

    // Draw grid.
    const int firstLeftGridLine = realLeft - (realLeft % gridSize);
    const int firstTopGridLine = realTop - (realTop % gridSize);

    QVarLengthArray<QLine, 100> lines;

    for (qreal x = firstLeftGridLine; x <= realRight; x += gridSize)
        lines.append(QLine(x, realTop, x, realBottom));
    for (qreal y = firstTopGridLine; y <= realBottom; y += gridSize)
        lines.append(QLine(realLeft, y, realRight, y));

    //painter->setRenderHint(QPainter::Antialiasing);
    painter->setPen(QPen(QColor(220, 220, 220), 0.0));
    painter->drawLines(lines.data(), lines.size());

    // Draw axes.
    painter->setPen(QPen(Qt::lightGray, 0.0));
    painter->drawLine(0, realTop, 0, realBottom);
    painter->drawLine(realLeft, 0, realRight, 0);
}

However, unless I turn on anti-aliasing, moving items around will sometimes leave artifacts in the grid (areas where it's not drawn). It seems it mostly happens at low zoom levels, when the view is zoomed out a bit. Any ideas what I might be doing wrong here?

I'd really don't want to turn anti-aliasing on since the lines are strictly horizontal and vertical, and I'd like them to be as crisp as possible.

Any help is much appriciated, Regards, Elvis

estan
  • 1,444
  • 2
  • 18
  • 29
  • Have you tried explicitly erasing the contents of the scene before drawing? Try drawing a rectangle of white (or whatever your background colour is) before drawing your gridlines, and see if that helps. – Thomi May 06 '10 at 07:48
  • Have you tried calling the base class function first? Maybe it is supposed to erase the background first: `QGraphicsScene::drawBackground(painter, rect)`, and then all your custom code. – ak. Dec 06 '10 at 16:05
  • have you tried calling setViewportUpdateMode(QGraphicsView::FullViewportUpdate) at the start of your program? – Tom Mar 23 '11 at 10:05

1 Answers1

2

Sounds like you need to use a different viewport update method:

http://doc.qt.io/qt-5/qgraphicsview.html#viewportUpdateMode-prop

and perhaps the background caching:

http://doc.qt.io/qt-5/qgraphicsview.html#cacheMode-prop

Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
Phil Hannent
  • 12,047
  • 17
  • 71
  • 118
  • I got the smiliar issue and it is fixed after I added "setViewportUpdateMode(QGraphicsView::FullViewportUpdate)", although not sure how is the performance impacted. – Vincent May 29 '12 at 07:49
  • Check my question which has a better solution than using full update: http://stackoverflow.com/questions/13933699/qgraphicslineitempaint-artifacts – paulm Dec 20 '12 at 13:26