Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. When changing item in QGraphicsScene, the old content is still displayed

When changing item in QGraphicsScene, the old content is still displayed

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 1 Posters 277 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtUser467
    wrote on last edited by
    #1

    I have a QGraphicsScene that contains some QGraphicsItem. One is a custom item derived from QGraphicsItem, something like so (simplified):

    class MyPath : public QGraphicsItem {
      public:
        enum { Type = UserType + 2 };
    
      public:
        MyPath();
        virtual int type() const override { return Type; }
        virtual QRectF boundingRect() const override;
    
        void start(const QPointF& p, double w);
        void stop(const QPointF& p, double w);
        void line_to(const QPointF& p, double w);
    
        virtual void paint(QPainter* painter,
                           const QStyleOptionGraphicsItem* option,
                           QWidget* widget = nullptr) override;
    
      private:
        QPen _pen;
        Path _xy_path;
        QPainterPath _path;
    };
    

    The implementation is like this:

    void MyPath::start(const QPointF& p) {
        prepareGeometryChange();
        _path.moveTo(p);
        _xy_path.append(p);
    }
    
    void MyPath::stop(const QPointF& p) {
        prepareGeometryChange();
        _path.lineTo(p);
        _xy_path.append(p);
    
        // simplify the path
        _xy_path.douglas_peucker(5);
    
        prepareGeometryChange();
        _path.clear();
    
        _path.moveTo(_xy_path[0]);
        const auto size = _xy_path.size();
        for (int i = 0; i < size; i++) _path.lineTo(_xy_path[i]);
    }
    
    void MyPath::line_to(const QPointF& p) {
        prepareGeometryChange();
        _path.lineTo(p);
        _xy_path.append(p);
    }
    
    QRectF MyPath::boundingRect() const {
        double delta = _pen.width() / 2.0 + 5;
        QRectF rect = _path.boundingRect();
        rect.adjust(-delta, -delta, delta, delta);
        return rect;
    }
    
    void MyPath::paint(QPainter* painter,
                           const QStyleOptionGraphicsItem* option,
                           QWidget* widget) {
        painter->save();
        painter->setPen(_pen);
        painter->drawPath(_path);
        painter->restore();
    }
    
    

    The problem now is that the old drawing remains on the screen even when the old path is erased. The new, simplified path is just drawn on top. Here is an example:
    the straight line segments should be there, but the hand-drawn line should have disappeared.

    qgraphicsitem.png.png

    It seems like prepareGeometryChange() is not sufficient to make the old line disappear, which I would have assumed. How do I do this properly?

    Q 1 Reply Last reply
    0
    • Q QtUser467

      I have a QGraphicsScene that contains some QGraphicsItem. One is a custom item derived from QGraphicsItem, something like so (simplified):

      class MyPath : public QGraphicsItem {
        public:
          enum { Type = UserType + 2 };
      
        public:
          MyPath();
          virtual int type() const override { return Type; }
          virtual QRectF boundingRect() const override;
      
          void start(const QPointF& p, double w);
          void stop(const QPointF& p, double w);
          void line_to(const QPointF& p, double w);
      
          virtual void paint(QPainter* painter,
                             const QStyleOptionGraphicsItem* option,
                             QWidget* widget = nullptr) override;
      
        private:
          QPen _pen;
          Path _xy_path;
          QPainterPath _path;
      };
      

      The implementation is like this:

      void MyPath::start(const QPointF& p) {
          prepareGeometryChange();
          _path.moveTo(p);
          _xy_path.append(p);
      }
      
      void MyPath::stop(const QPointF& p) {
          prepareGeometryChange();
          _path.lineTo(p);
          _xy_path.append(p);
      
          // simplify the path
          _xy_path.douglas_peucker(5);
      
          prepareGeometryChange();
          _path.clear();
      
          _path.moveTo(_xy_path[0]);
          const auto size = _xy_path.size();
          for (int i = 0; i < size; i++) _path.lineTo(_xy_path[i]);
      }
      
      void MyPath::line_to(const QPointF& p) {
          prepareGeometryChange();
          _path.lineTo(p);
          _xy_path.append(p);
      }
      
      QRectF MyPath::boundingRect() const {
          double delta = _pen.width() / 2.0 + 5;
          QRectF rect = _path.boundingRect();
          rect.adjust(-delta, -delta, delta, delta);
          return rect;
      }
      
      void MyPath::paint(QPainter* painter,
                             const QStyleOptionGraphicsItem* option,
                             QWidget* widget) {
          painter->save();
          painter->setPen(_pen);
          painter->drawPath(_path);
          painter->restore();
      }
      
      

      The problem now is that the old drawing remains on the screen even when the old path is erased. The new, simplified path is just drawn on top. Here is an example:
      the straight line segments should be there, but the hand-drawn line should have disappeared.

      qgraphicsitem.png.png

      It seems like prepareGeometryChange() is not sufficient to make the old line disappear, which I would have assumed. How do I do this properly?

      Q Offline
      Q Offline
      QtUser467
      wrote on last edited by
      #2

      Upon further inspection, it turned out that the problem only occurs when the widget containing the QGraphicsView has the attribute Qt::WA_TranslucentBackground set.

      setAttribute(Qt::WA_TranslucentBackground);
      

      Is this really the intended behaviour or might this be a bug?

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved