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. [SOLVED]Qt 5.2.1 GraphicsView::drawBackground and drawForeground are not called after GraphicsView::Update()

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

Scheduled Pinned Locked Moved General and Desktop
8 Posts 3 Posters 6.9k 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.
  • P Offline
    P Offline
    peruserkki
    wrote on last edited by
    #1

    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
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      One way is to invalidate the scene rectangle:

      scene()->invalidate(scene()->sceneRect());
      
      1 Reply Last reply
      0
      • P Offline
        P Offline
        peruserkki
        wrote on last edited by
        #3

        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
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by Chris Kawa
          #4

          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
          0
          • P Offline
            P Offline
            peruserkki
            wrote on last edited by Chris Kawa
            #5

            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
            0
            • P Offline
              P Offline
              peruserkki
              wrote on last edited by
              #6

              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
              0
              • P Offline
                P Offline
                peruserkki
                wrote on last edited by
                #7

                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
                0
                • beartreeB Offline
                  beartreeB Offline
                  beartree
                  wrote on last edited by
                  #8

                  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
                  0

                  • Login

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