title: How to refresh QGraphicsView to show changes in the QGraphicsScene's background
body: <p>I have a custom <code>QGraphicsView</code> and <code>QGraphicsScene</code>. Inside <code>QGraphicsScene</code> I have overriden <code>void drawBackground(QPainter *painter, const QRectF &amp;rect)</code> and based on a boolean flag I want to toggle a grid on and off. I tried calling <code>clear()</code> or calling the <code>painter</code>'s <code>eraseRect(sceneRect())</code> inside my function but it didn't work. So after doing some reading I guess it wasn't supposed to work since after changing the scene you need to refresh the view. That's why I'm emitting a signal called <code>signalUpdateViewport()</code></p>
  
  <pre><code>void Scene::drawBackground(QPainter *painter, const QRectF &amp;rect) {
      if(this-&gt;gridEnabled) {
          // Draw grid
      }
      else {
          // Erase using the painter
          painter-&gt;eraseRect(sceneRect());
          // or by calling
          //clear();
      }
  
      // Trigger refresh of view
      emit signalUpdateViewport();
      QGraphicsScene::drawBackground(painter, rect);
  }
  </code></pre>
  
  <p>which is then captured by my view:</p>
  
  <pre><code>void View::slotUpdateViewport() {
      this-&gt;viewport()-&gt;update();
  }
  </code></pre>
  
  <p>Needless to say this didn't work. With <strong>doesn't work</strong> I mean that the results (be it a refresh from inside the scene or inside the view) are made visible only when changing the widget for example triggering a resize event.</p>
  
  <p>How do I properly refresh the view to my scene to display the changed that I have made in the scene's background?</p>
  
  <p>The code:</p>
  
  <p><strong>scene.h</strong></p>
  
  <pre><code>#ifndef SCENE_HPP
  #define SCENE_HPP
  
  #include &lt;QGraphicsScene&gt;
  
  class View;
  
  class Scene : public QGraphicsScene
  {
      Q_OBJECT
      Q_ENUMS(Mode)
      Q_ENUMS(ItemType)
    public:
      enum Mode { Default, Insert, Select };
      enum ItemType { None, ConnectionCurve, ConnectionLine, Node };
  
      Scene(QObject* parent = Q_NULLPTR);
      ~Scene();
  
      void setMode(Mode mode, ItemType itemType);
    signals:
      void signalCursorCoords(int x, int y);
  
      void signalSceneModeChanged(Scene::Mode sceneMode);
      void signalSceneItemTypeChanged(Scene::ItemType sceneItemType);
      void signalGridDisplayChanged(bool gridEnabled);
  
      void signalUpdateViewport();
    public slots:
      void slotSetSceneMode(Scene::Mode sceneMode);
      void slotSetSceneItemType(Scene::ItemType sceneItemType);
  
      void slotSetGridStep(int gridStep);
      void slotToggleGrid(bool flag);
    private:
      Mode sceneMode;
      ItemType sceneItemType;
  
      bool gridEnabled;
      int gridStep;
  
      void makeItemsControllable(bool areControllable);
      double round(double val);
    protected:
      void mousePressEvent(QGraphicsSceneMouseEvent *event);
      void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
      void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
      void keyPressEvent(QKeyEvent *event);
  
      void drawBackground(QPainter *painter, const QRectF &amp;rect);
  };
  
  Q_DECLARE_METATYPE(Scene::Mode)
  Q_DECLARE_METATYPE(Scene::ItemType)
  
  #endif // SCENE_HPP
  </code></pre>
  
  <p><strong>scene.cpp</strong></p>
  
  <pre><code>#include &lt;QGraphicsItem&gt;
  #include &lt;QGraphicsView&gt;
  #include &lt;QGraphicsSceneMouseEvent&gt;
  #include &lt;QPainter&gt;
  #include &lt;QRectF&gt;
  #include &lt;QKeyEvent&gt;
  
  #include &lt;QtDebug&gt;
  
  #include "scene.h"
  
  Scene::Scene(QObject* parent)
      : QGraphicsScene (parent),
        sceneMode(Default),
        sceneItemType(None),
        gridEnabled(true),
        gridStep(30)
  {
  
  }
  
  Scene::~Scene()
  {
  }
  
  void Scene::setMode(Mode mode, ItemType itemType)
  {
    this-&gt;sceneMode = mode;
    this-&gt;sceneItemType = itemType;
  
    QGraphicsView::DragMode vMode = QGraphicsView::NoDrag;
  
    switch(mode) {
      case Insert:
      {
        makeItemsControllable(false);
        vMode = QGraphicsView::NoDrag;
        break;
      }
      case Select:
      {
        makeItemsControllable(true);
        vMode = QGraphicsView::RubberBandDrag;
        break;
      }
      case Default:
      {
        makeItemsControllable(false);
        vMode = QGraphicsView::NoDrag;
        break;
      }
    }
  
    QGraphicsView* mView = views().at(0);
    if(mView) {
      mView-&gt;setDragMode(vMode);
    }
  }
  
  void Scene::slotSetSceneMode(Scene::Mode sceneMode)
  {
    this-&gt;sceneMode = sceneMode;
    qDebug() &lt;&lt; "SM" &lt;&lt; (int)this-&gt;sceneMode;
    emit signalSceneModeChanged(this-&gt;sceneMode);
  }
  
  void Scene::slotSetSceneItemType(Scene::ItemType sceneItemType)
  {
    this-&gt;sceneItemType = sceneItemType;
    qDebug() &lt;&lt; "SIT:" &lt;&lt; (int)this-&gt;sceneItemType;
    emit signalSceneItemTypeChanged(this-&gt;sceneItemType);
  }
  
  void Scene::slotSetGridStep(int gridStep)
  {
    this-&gt;gridStep = gridStep;
  }
  
  void Scene::slotToggleGrid(bool flag)
  {
    this-&gt;gridEnabled = flag;
    invalidate(sceneRect(), BackgroundLayer);
    qDebug() &lt;&lt; "Grid " &lt;&lt; (this-&gt;gridEnabled ? "enabled" : "disabled");
    update(sceneRect());
    emit signalGridDisplayChanged(this-&gt;gridEnabled);
  }
  
  void Scene::makeItemsControllable(bool areControllable)
  {
    foreach(QGraphicsItem* item, items()) {
      if(/*item-&gt;type() == QCVN_Node_Top::Type
         ||*/ item-&gt;type() == QGraphicsLineItem::Type
         || item-&gt;type() == QGraphicsPathItem::Type) {
        item-&gt;setFlag(QGraphicsItem::ItemIsMovable, areControllable);
        item-&gt;setFlag(QGraphicsItem::ItemIsSelectable, areControllable);
      }
    }
  }
  
  double Scene::round(double val)
  {
    int tmp = int(val) + this-&gt;gridStep/2;
    tmp -= tmp % this-&gt;gridStep;
    return double(tmp);
  }
  
  void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
  {
    QGraphicsScene::mousePressEvent(event);
  }
  
  void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
  {
    emit signalCursorCoords(int(event-&gt;scenePos().x()), int(event-&gt;scenePos().y()));
    QGraphicsScene::mouseMoveEvent(event);
  }
  
  void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
  {
    QGraphicsScene::mouseReleaseEvent(event);
  }
  
  void Scene::keyPressEvent(QKeyEvent* event)
  {
    if(event-&gt;key() == Qt::Key_M) {
      slotSetSceneMode(static_cast&lt;Mode&gt;((int(this-&gt;sceneMode) + 1) % 3));
    }
    else if(event-&gt;key() == Qt::Key_G) {
      slotToggleGrid(!this-&gt;gridEnabled);
    }
  
    QGraphicsScene::keyPressEvent(event);
  }
  
  void Scene::drawBackground(QPainter *painter, const QRectF &amp;rect)
  {
    // FIXME Clearing and drawing the grid happens only when scene size or something else changes
    if(this-&gt;gridEnabled) {
      painter-&gt;setPen(QPen(QColor(200, 200, 255, 125)));
      // draw horizontal grid
      double start = round(rect.top());
      if (start &gt; rect.top()) {
        start -= this-&gt;gridStep;
      }
      for (double y = start - this-&gt;gridStep; y &lt; rect.bottom(); ) {
        y += this-&gt;gridStep;
        painter-&gt;drawLine(int(rect.left()), int(y), int(rect.right()), int(y));
      }
      // now draw vertical grid
      start = round(rect.left());
      if (start &gt; rect.left()) {
        start -= this-&gt;gridStep;
      }
      for (double x = start - this-&gt;gridStep; x &lt; rect.right(); x += this-&gt;gridStep) {
        painter-&gt;drawLine(int(x), int(rect.top()), int(x), int(rect.bottom()));
      }
    }
    else {
      // Erase whole scene's background
      painter-&gt;eraseRect(sceneRect());
    }
  
    slotToggleGrid(this-&gt;gridEnabled);
  
    QGraphicsScene::drawBackground(painter, rect);
  }
  </code></pre>
  
  <p>The <code>View</code> currently doesn't contain anything - all is default. The setting of my <code>Scene</code> and <code>View</code> instance inside my <code>QMainWindow</code> is as follows:</p>
  
  <pre><code>void App::initViewer()
  {
    this-&gt;scene = new Scene(this);
    this-&gt;view = new View(this-&gt;scene, this);
    this-&gt;viewport = new QGLWidget(QGLFormat(QGL::SampleBuffers), this-&gt;view);
    this-&gt;view-&gt;setRenderHints(QPainter::Antialiasing);
    this-&gt;view-&gt;setViewport(this-&gt;viewport);
    this-&gt;view-&gt;setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    this-&gt;view-&gt;setCacheMode(QGraphicsView::CacheBackground);
  
    setCentralWidget(this-&gt;view);
  }
  </code></pre>
  
  <p><strong>EDIT:</strong>  I tried calling invalidate(<code>sceneRect()</code>, <code>BackgroundLayer</code>) before the <code>update()</code>, <code>clear()</code> or whatever I tried to trigger a refresh. </p>
  
  <p>I also tried <code>QGraphicsScene::update()</code> from within the scene but it didn't work Passing both no argument to the function call and then passing <code>sceneRect()</code> didn't result in anything different then what I've described above.</p>