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. QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent
Forum Updated to NodeBB v4.3 + New Features

QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.8k Views 2 Watching
  • 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.
  • dporobicD Offline
    dporobicD Offline
    dporobic
    wrote on last edited by
    #1

    I run into an issue and can't figure out what I'm doing wrong. I'm trying to show this overlay text in the bottom right corner of my view (yes, the 100% down there), the text is shown correctly as long as I don't scroll (resizing the whole widget seems to be ok). As soon as I scroll, I get those artifacts as if only a part of the area is repainted.

    Before Scrolling, ok:
    fba222c6-1ef7-4893-b6e1-7893d6578309-image.png

    After resizing the whole window, making the view smaller, ok:
    29a4844c-1222-4cb5-a8f9-b070f3f45aec-image.png

    Scrolling down, not so ok:
    f07e2313-f8fa-4c6b-a0c8-b8334e3d51da-image.png

    This is how I draw the text, nothing special.

    void AnnotationView::paintEvent(QPaintEvent *event)
    {
    	QGraphicsView::paintEvent(event);
    
    	auto viewPort = viewport();
    	if(viewPort != nullptr){
    		QPainter painter(viewPort);
    		auto rect = event->rect().adjusted(0, 0, -2, -2);
    		auto alignment = Qt::AlignRight | Qt::AlignBottom;
    		auto value = qRound(mAnnotationViewZoomer->zoomValue() * 100);
    		auto text = QString::number(value) + QLatin1Literal("%");
    		painter.drawText(rect, alignment, text);
    	}
    }
    

    The paintEvent method seems to be called even when scrolling but the result doesn't seem to be correct.

    Any ideas what I'm dong wrong?

    https://github.com/ksnip/ksnip

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #13

      Hi
      You can also try setting
      ViewportUpdateMode to FullViewportUpdate for test.
      Default is MinimalViewportUpdate

      dporobicD 1 Reply Last reply
      2
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        event->rect() returns the changed rect/ the rect to redraw, not the rect of the viewport.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        dporobicD 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          event->rect() returns the changed rect/ the rect to redraw, not the rect of the viewport.

          dporobicD Offline
          dporobicD Offline
          dporobic
          wrote on last edited by
          #3

          @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

          event->rect() returns the changed rect/ the rect to redraw, not the rect of the viewport.

          What would be the proper way to do id? Do I need to the the view to repaint the full ViewPort rect when scroll is happening?

          https://github.com/ksnip/ksnip

          1 Reply Last reply
          0
          • Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            You should paint at the correct position instead the lower right corner of a rect which should be currently updated. This rect just informs you where painting is needed, you use it to place your text.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            dporobicD 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              You should paint at the correct position instead the lower right corner of a rect which should be currently updated. This rect just informs you where painting is needed, you use it to place your text.

              dporobicD Offline
              dporobicD Offline
              dporobic
              wrote on last edited by
              #5

              @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

              You should paint at the correct position instead the lower right corner of a rect which should be currently updated. This rect just informs you where painting is needed, you use it to place your text.

              This means that this here should be working, right? I'm painting in the lower right corner of the view port rect, that should be the whole thing? But it behaves the same:

              void AnnotationView::paintEvent(QPaintEvent *event)
              {
              	QGraphicsView::paintEvent(event);
              
              	auto viewPort = viewport();
              	if(viewPort != nullptr){
              		QPainter painter(viewPort);
              		auto rect = viewPort->rect().adjusted(0, 0, -2, -2);
              		auto alignment = Qt::AlignRight | Qt::AlignBottom;
              		auto value = qRound(mAnnotationViewZoomer->zoomValue() * 100);
              		auto text = QString::number(value) + QLatin1Literal("%");
              		painter.drawText(rect, alignment, text);
              	}
              }
              

              Or how else can I get the bottom right corner of the viewport?

              https://github.com/ksnip/ksnip

              Christian EhrlicherC 1 Reply Last reply
              0
              • dporobicD dporobic

                @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                You should paint at the correct position instead the lower right corner of a rect which should be currently updated. This rect just informs you where painting is needed, you use it to place your text.

                This means that this here should be working, right? I'm painting in the lower right corner of the view port rect, that should be the whole thing? But it behaves the same:

                void AnnotationView::paintEvent(QPaintEvent *event)
                {
                	QGraphicsView::paintEvent(event);
                
                	auto viewPort = viewport();
                	if(viewPort != nullptr){
                		QPainter painter(viewPort);
                		auto rect = viewPort->rect().adjusted(0, 0, -2, -2);
                		auto alignment = Qt::AlignRight | Qt::AlignBottom;
                		auto value = qRound(mAnnotationViewZoomer->zoomValue() * 100);
                		auto text = QString::number(value) + QLatin1Literal("%");
                		painter.drawText(rect, alignment, text);
                	}
                }
                

                Or how else can I get the bottom right corner of the viewport?

                Christian EhrlicherC Online
                Christian EhrlicherC Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #6

                @dporobic I would guess yes, simply try it out.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                dporobicD 1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  @dporobic I would guess yes, simply try it out.

                  dporobicD Offline
                  dporobicD Offline
                  dporobic
                  wrote on last edited by
                  #7

                  @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                  @dporobic I would guess yes, simply try it out.

                  I have tried it out, even before I have posted here (and now again) and the result was the same, that's why I assumed the rect from viewport and event are the same.

                  Here how it looks like:
                  7dc1e9b3-426d-45ba-aaf1-71e80b55f746-image.png

                  https://github.com/ksnip/ksnip

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Online
                    Christian EhrlicherC Online
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    Did you print the coordinates of the rect? Please provide a minimal, compilable example.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    dporobicD 1 Reply Last reply
                    0
                    • Christian EhrlicherC Christian Ehrlicher

                      Did you print the coordinates of the rect? Please provide a minimal, compilable example.

                      dporobicD Offline
                      dporobicD Offline
                      dporobic
                      wrote on last edited by dporobic
                      #9

                      @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                      Did you print the coordinates of the rect?

                      Following code:

                      void AnnotationView::paintEvent(QPaintEvent *event)
                      {
                      	QGraphicsView::paintEvent(event);
                      
                      	auto viewPort = viewport();
                      	if(viewPort != nullptr){
                      		QPainter painter(viewPort);
                      		auto rect = viewPort->rect().adjusted(0, 0, -2, -2);
                      		auto rect2 = event->rect();
                      		qDebug("ViewPort -> x: %s, y: %s, w: %s, h: %s", qPrintable(QString::number(rect.x())), qPrintable(QString::number(rect.y())), qPrintable(QString::number(rect.width())), qPrintable(QString::number(rect.height())));
                      		qDebug("Event -> x: %s, y: %s, w: %s, h: %s", qPrintable(QString::number(rect2.x())), qPrintable(QString::number(rect2.y())), qPrintable(QString::number(rect2.width())), qPrintable(QString::number(rect2.height())));
                      		auto alignment = Qt::AlignRight | Qt::AlignBottom;
                      		auto value = qRound(mAnnotationViewZoomer->zoomValue() * 100);
                      		auto text = QString::number(value) + QLatin1Literal("%");
                      		painter.drawText(rect, alignment, text);
                      	}
                      }
                      

                      Gives me this output when scrolling to the bottom, as you said, the rects are not the same (those are the last four entires):

                      ...
                      ViewPort -> x: 0, y: 0, w: 288, h: 229
                      Event -> x: 0, y: 224, w: 290, h: 7
                      ViewPort -> x: 0, y: 0, w: 288, h: 229
                      Event -> x: 0, y: 228, w: 290, h: 3
                      ViewPort -> x: 0, y: 0, w: 288, h: 229
                      Event -> x: 0, y: 0, w: 290, h: 231
                      ViewPort -> x: 0, y: 0, w: 288, h: 229
                      Event -> x: 0, y: 0, w: 290, h: 231
                      ViewPort -> x: 0, y: 0, w: 288, h: 229
                      Event -> x: 0, y: 0, w: 290, h: 231
                      

                      And this is how the output looks like:
                      2b4f5130-3c95-4ac5-8896-58bd5b2067d5-image.png

                      @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                      Please provide a minimal, compilable example.

                      I can provide one later.

                      https://github.com/ksnip/ksnip

                      J.HilkJ 1 Reply Last reply
                      1
                      • dporobicD dporobic

                        @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                        Did you print the coordinates of the rect?

                        Following code:

                        void AnnotationView::paintEvent(QPaintEvent *event)
                        {
                        	QGraphicsView::paintEvent(event);
                        
                        	auto viewPort = viewport();
                        	if(viewPort != nullptr){
                        		QPainter painter(viewPort);
                        		auto rect = viewPort->rect().adjusted(0, 0, -2, -2);
                        		auto rect2 = event->rect();
                        		qDebug("ViewPort -> x: %s, y: %s, w: %s, h: %s", qPrintable(QString::number(rect.x())), qPrintable(QString::number(rect.y())), qPrintable(QString::number(rect.width())), qPrintable(QString::number(rect.height())));
                        		qDebug("Event -> x: %s, y: %s, w: %s, h: %s", qPrintable(QString::number(rect2.x())), qPrintable(QString::number(rect2.y())), qPrintable(QString::number(rect2.width())), qPrintable(QString::number(rect2.height())));
                        		auto alignment = Qt::AlignRight | Qt::AlignBottom;
                        		auto value = qRound(mAnnotationViewZoomer->zoomValue() * 100);
                        		auto text = QString::number(value) + QLatin1Literal("%");
                        		painter.drawText(rect, alignment, text);
                        	}
                        }
                        

                        Gives me this output when scrolling to the bottom, as you said, the rects are not the same (those are the last four entires):

                        ...
                        ViewPort -> x: 0, y: 0, w: 288, h: 229
                        Event -> x: 0, y: 224, w: 290, h: 7
                        ViewPort -> x: 0, y: 0, w: 288, h: 229
                        Event -> x: 0, y: 228, w: 290, h: 3
                        ViewPort -> x: 0, y: 0, w: 288, h: 229
                        Event -> x: 0, y: 0, w: 290, h: 231
                        ViewPort -> x: 0, y: 0, w: 288, h: 229
                        Event -> x: 0, y: 0, w: 290, h: 231
                        ViewPort -> x: 0, y: 0, w: 288, h: 229
                        Event -> x: 0, y: 0, w: 290, h: 231
                        

                        And this is how the output looks like:
                        2b4f5130-3c95-4ac5-8896-58bd5b2067d5-image.png

                        @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                        Please provide a minimal, compilable example.

                        I can provide one later.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #10

                        @dporobic what version of QT are you using, and can you try it against an other one (newer) ?


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        dporobicD 1 Reply Last reply
                        0
                        • J.HilkJ J.Hilk

                          @dporobic what version of QT are you using, and can you try it against an other one (newer) ?

                          dporobicD Offline
                          dporobicD Offline
                          dporobic
                          wrote on last edited by
                          #11

                          @J-Hilk said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                          @dporobic what version of QT are you using, and can you try it against an other one (newer) ?

                          I'm using 5.9.9 on a Windows machine. I can try later on my Linux which has 5.12.7.

                          https://github.com/ksnip/ksnip

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Online
                            Christian EhrlicherC Online
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by Christian Ehrlicher
                            #12

                            Since you want to paint on a region which needs no update according to the paint event I would suggest you to call update on the complete viewport to see if this helps - just for testing of course.
                            Since the viewport is moving it's not a normal use case to paint something on a fixed (from the widget pov) position, therefore all the problems here.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            dporobicD 1 Reply Last reply
                            3
                            • mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #13

                              Hi
                              You can also try setting
                              ViewportUpdateMode to FullViewportUpdate for test.
                              Default is MinimalViewportUpdate

                              dporobicD 1 Reply Last reply
                              2
                              • Christian EhrlicherC Christian Ehrlicher

                                Since you want to paint on a region which needs no update according to the paint event I would suggest you to call update on the complete viewport to see if this helps - just for testing of course.
                                Since the viewport is moving it's not a normal use case to paint something on a fixed (from the widget pov) position, therefore all the problems here.

                                dporobicD Offline
                                dporobicD Offline
                                dporobic
                                wrote on last edited by
                                #14

                                @Christian-Ehrlicher said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                                Since you want to paint on a region which needs no update according to the paint event I would suggest you to call update on the complete viewport to see if this helps - just for testing of course.
                                Since the viewport is moving it's not a normal use case to paint something on a fixed (from the widget pov) position, therefore all the problems here.

                                My View can be scrolled by dragging while holding down the middle mouse key, so that's where I put the repaint method:

                                void AnnotationView::mouseMoveEvent(QMouseEvent *event)
                                {
                                	if(mIsDragging) {
                                		qDebug("Scroll to");
                                		scrollTo(event->pos());
                                		qDebug("Repaint");
                                		repaint(viewport()->rect());   // Here the repaint
                                		return;
                                	}
                                	QGraphicsView::mouseMoveEvent(event);
                                }
                                
                                void AnnotationView::scrollTo(const QPoint &pos)
                                {
                                	auto delta = pos - mLastPosition;
                                	scrollByDelta(horizontalScrollBar(), delta.x());
                                	scrollByDelta(verticalScrollBar(), delta.y());
                                	mLastPosition = pos;
                                }
                                
                                void AnnotationView::scrollByDelta(QScrollBar *scrollBar, int delta) const
                                {
                                	scrollBar->setValue(scrollBar->value() - delta);
                                }
                                

                                This is the output that I get:

                                ...
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                Scroll to
                                Repaint
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                Scroll to
                                Repaint
                                Scroll to
                                Repaint
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                Scroll to
                                Repaint
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                Scroll to
                                Repaint
                                Scroll to
                                Repaint
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                Scroll to
                                Repaint
                                Scroll to
                                Repaint
                                ViewPort -> x: 0, y: 0, w: 288, h: 229
                                Event -> x: 0, y: 230, w: 290, h: 1
                                

                                This is how it looks like in the application (the red arrow shows the direction of dragging):
                                3c64554c-de2e-41af-9cf3-59de09c0aaf6-image.png

                                When I do a single click on the view (where the red dot is), everything is repainted correctly:
                                53b99d88-bceb-4f40-a8f8-9cace41975ee-image.png

                                Using update or repaint behaves the same, couldn't see any difference. Also same with passing the viewPort rect or calling them without parameter. I have also noticed that slowly dragging leaves less artifacts behind, almost non when you're really slow. Dragging fast leaves is like on the screenshot.

                                https://github.com/ksnip/ksnip

                                1 Reply Last reply
                                0
                                • mrjjM mrjj

                                  Hi
                                  You can also try setting
                                  ViewportUpdateMode to FullViewportUpdate for test.
                                  Default is MinimalViewportUpdate

                                  dporobicD Offline
                                  dporobicD Offline
                                  dporobic
                                  wrote on last edited by
                                  #15

                                  @mrjj said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                                  Hi
                                  You can also try setting
                                  ViewportUpdateMode to FullViewportUpdate for test.
                                  Default is MinimalViewportUpdate

                                  This works, the text is always written in the bottom right corner, no artifacts. I have also tested the other 4 mods, the FullViewportUpdate seems to be the only one working.
                                  Is this effecting the repainting of the underlying Scene?

                                  https://github.com/ksnip/ksnip

                                  mrjjM 1 Reply Last reply
                                  0
                                  • dporobicD dporobic

                                    @mrjj said in QGraphicsView doesn't repaint correctly after scrolling with overwritten paintEvent:

                                    Hi
                                    You can also try setting
                                    ViewportUpdateMode to FullViewportUpdate for test.
                                    Default is MinimalViewportUpdate

                                    This works, the text is always written in the bottom right corner, no artifacts. I have also tested the other 4 mods, the FullViewportUpdate seems to be the only one working.
                                    Is this effecting the repainting of the underlying Scene?

                                    mrjjM Offline
                                    mrjjM Offline
                                    mrjj
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #16

                                    @dporobic
                                    Hi
                                    yes, it switches from partial/clever updating to full redraw.
                                    So it might have performance complications with a huge number of items.
                                    You can test with the 40000 example and see how much/if it matters.
                                    https://doc.qt.io/qt-5/qtwidgets-graphicsview-chip-example.html

                                    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