Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    [SOLVED]Qt 5.2.1 GraphicsView::drawBackground and drawForeground are not called after GraphicsView::Update()

    General and Desktop
    3
    8
    6144
    Loading More Posts
    • 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.
    • P
      peruserkki last edited by

      Hi.

      We are porting application from Qt4.8.x to Qt5.x. So far the task has been easy. Now we have one problem.

      In Q4.8, inside subclassed QGraphicsView::mouseMoveEvent we call "this->update();" that results call of GraphicsView::paint and QGraphicsView::drawBackground and ..drawForeground.

      This is not happening in Qt5.2.1. How QGraphicsView::drawBackground (paint event) can be generated in Qt5.x?

      ..drawBackground is called if we use CenterOn-function for example.

      Kind regards,
      Erkki
      Tampere, Finland

      Erkki
      Find the bug, Fix the bug, Do it fewer times!

      1 Reply Last reply Reply Quote 0
      • Chris Kawa
        Chris Kawa Moderators last edited by Chris Kawa

        One way is to invalidate the scene rectangle:

        scene()->invalidate(scene()->sceneRect());
        
        1 Reply Last reply Reply Quote 0
        • P
          peruserkki last edited by

          Some unknown reason it ( scene()->invalidate(scene()->sceneRect()); ) does not generate paint event to QGraphicsview (logged both mouse and paint event).

          The update mode is QGraphicsView::BoundingRectViewportUpdate.

          I can generate paint-events by calling function centerOn. Problem of that solution is that picture drifts a little on every mousemove event.

          Erkki
          Find the bug, Fix the bug, Do it fewer times!

          1 Reply Last reply Reply Quote 0
          • Chris Kawa
            Chris Kawa Moderators last edited by Chris Kawa

            Can you show your code? I tried this and it works just fine:

            class GV : public QGraphicsView {
            public:
                GV(QWidget* parent = nullptr) : QGraphicsView(parent) {
                    setMouseTracking(true);
                }
                void paintEvent(QPaintEvent* evt) {
                    qDebug() << "paintEvent";
                    QGraphicsView::paintEvent(evt);
                }
                void drawBackground(QPainter* p, const QRectF& r) {
                    qDebug() << "drawBackground";
                    QGraphicsView::drawBackground(p,r);
                }
                void mouseMoveEvent(QMouseEvent* evt) {
                    qDebug() << "mouseMoveEvent";
                    QGraphicsView::mouseMoveEvent(evt);
                    scene()->invalidate(scene()->sceneRect());
                }
            };
            
            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
                auto gv = new GV(this);
                gv->setScene(new QGraphicsScene(this));
                setCentralWidget(gv);
            }
            

            Output when I hover mouse over graphics view is:

            mouseMoveEvent 
            paintEvent 
            drawBackground 
            mouseMoveEvent 
            paintEvent 
            drawBackground 
            mouseMoveEvent 
            paintEvent 
            drawBackground 
            ...
            
            1 Reply Last reply Reply Quote 0
            • P
              peruserkki last edited by Chris Kawa

              First, thanks for bullet proof example!

              I checked your example it looks that I am doing things similar way.

              Here is the code (I can mail whole file if needed):

              Initialization of instance:

              #if 0
                  setRenderHints(DEFAULT_RENDER_HINTS);
                  /* optimization mode */
                  setOptimizationFlags (
                                        QGraphicsView::DontAdjustForAntialiasing);
              #else    
                  setRenderHints( QPainter::TextAntialiasing);
              #endif
                  setCacheMode(QGraphicsView::CacheNone);
              
                  setCursor(Qt::ArrowCursor);
                  setInteractive (true);
                  setMouseTracking(true);
              
              
                  setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
              
                  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
              
                  setAlignment(DATA_ALIGNMENT); // align data to bottom.
              

              Paint:

              void timelinegraphicsdataview::paintEvent ( QPaintEvent * event )
              {
              #ifdef TIMELINEGRAPHICSVIEWPERFORMANCEDEBUG
                  FUNCTIONSCOPE;
              #endif
              
                  LOGFREETEXT("paintEvent");
              
              
                  if (event==NULL) return;  // do not handle null event
              
                  if( ( IsViewOn() == true && mCanPaint == true )
                     || mInfoText.length()> 0 )
                  {
                      QElapsedTimer mgfx_render_timer;
              
                      mgfx_render_timer.start();
                      
                      if (mFirstPaintAfterLoad==true)
                      {
                          /* Update channel height information */
                          /* Do here adjustments needed after 1st load */
                          mFirstPaintAfterLoad = false;
                      }
              
                      /* Paint */
                      QGraphicsView::paintEvent ( event );
              
                      // Statusbar text
                      QString a;
                      mperf_gfx_render_time_ms = mgfx_render_timer.elapsed();
              
              #ifdef TIMELINEGRAPHICSVIEWPERFORMANCEDEBUGSTATS        
                      LOGVALUE("Screen Paint Time",mperf_gfx_render_time_ms)
              #endif
                              if (mperf_gfx_render_time_ms>0)
                      {
              
              #ifdef TIMELINEGRAPHICSVIEWPERFORMANCEDEBUGSTATS
                          StringInt renderGroup("timelinegraphicsdataview Render");
                          DebugAPI::Instance()->StoreDebugValue(renderGroup, "time", QString("%1ms").arg(mperf_gfx_render_time_ms));
              #endif
                      }
                  }
              }
              

              MouseMove:

              void timelinegraphicsdataview::mouseMoveEvent(QMouseEvent* event)
              {    
                  FUNCTIONSCOPE;
               /* Enable UI once data is available on screen */
                  if (mJamUI == false && event!=NULL && mCanPaint == true)
                  {
                      if(IsViewOn() == true)
                      {            
              
                          LOGFREETEXT("Scene update");            
                          scene()->invalidate(scene()->sceneRect());
              
                        ... <snipped something since posting has size limit >
              
              ementSec,mChannelToBeOffsetAdjusted);
              
                              /* This is needed for updating value abs graphs */
                              RefreshAllviews_slot();
                          }
              
                          /* trigger one update that causes background draw
                         and hence crosshair update */
                         this->update();
                      }       
                  }
                  if (event!=NULL)
                  {
                      QGraphicsView::mouseMoveEvent(event); //forward event)
                  }
              }
              

              When dealing with Qt 4.8.2, line 23 on above snippet generates paint event. I added your recommendation to line 11. When logging, proper mousemove events are generated but paint events not.

              Our application uses QML for layouting widgets to screen. I am wondering if during porting we messed something there and it prevents somehow update() from working like earlier.

              Erkki
              Find the bug, Fix the bug, Do it fewer times!

              1 Reply Last reply Reply Quote 0
              • P
                peruserkki last edited by

                I have been reading Qt5 material. There are some mention about Qt5 paint update differences. I will check those.

                Erkki
                Find the bug, Fix the bug, Do it fewer times!

                1 Reply Last reply Reply Quote 0
                • P
                  peruserkki last edited by

                  We had problems in porting to QML. We did some refactoring and subclassed items from QQuickView, made wrapper, forwarder events from QQuickView instance to wrapped class things started to work.

                  Erkki
                  Find the bug, Fix the bug, Do it fewer times!

                  1 Reply Last reply Reply Quote 0
                  • beartree
                    beartree last edited by

                    use QGraphicsView::resetCachedContent() to redraw background

                    Resets any cached content. Calling this function will clear QGraphicsView's cache. If the current cache mode is CacheNone, this function does nothing.
                    This function is called automatically for you when the backgroundBrush or QGraphicsScene::backgroundBrush properties change; you only need to call this function if you have reimplemented QGraphicsScene::drawBackground() or QGraphicsView::drawBackground() to draw a custom background, and need to trigger a full redraw.
                    See also cacheMode().

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post