Qt Forum

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

    QGraphicsView efficient offscreen painting

    General and Desktop
    1
    1
    1008
    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.
    • R
      RaubTieR last edited by

      Hello! My problem is following: I want a QGraphicsView to be rendered offscreen (say on QImage), and with minimum update rect as it is done by default.
      Before that I've already acheived full offscreen render: when QGraphicsScene::changed(QRectF) I would redraw through all the size (it takes ~100 ms). Now I want to only redraw a minimum rect, but the changed(QRectF) does not allow that, it always fires the maximum size rect.
      So I started to investigate Paint events of QGraphicsView::viewport(). However, there is no Paint events for invisible widgets, and my widgets of course are invisible as I render offscreen. But Paint event was so tempting with its QPaintEvent::rect(), that I even enabled visibility of actual widget for the moment. And it helped: as soon as widget had its own window it started to have all the Paint events and I got the render as required.

      Now the question is: how do I hide the actual widget, and still have its Paint events all the way?

      Event filter is capturing QPaintEvents for viewport. I try to make use of Qt::WA_DontShowOnScreen flag, with no success yet. As soon as actual widget is invisible I have no Paint events on mouse hovering the buttons, new widgets addition etc.

      P.S. I also consider use of the changed() signal if I can get minimal rect from there somehow.

      Here some codes attached:
      Constructor
      @mWidgetScene = new QGraphicsScene(this);
      mWidgetView = new QGraphicsView(mWidgetScene);
      mWidgetView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
      mWidgetView->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
      mWidgetView->viewport()->installEventFilter(this);
      //mWidgetView->setAttribute(Qt::WA_DontShowOnScreen); // comment to get it drawing
      mWidgetView->show();

      // tried this too
      //mWidgetView->viewport()->setAttribute(Qt::WA_DontShowOnScreen);
      //mWidgetView->viewport()->show();

      // somewhat scene activation for invisible cases
      //QEvent wsce(QEvent::WindowActivate);
      //QApplication::sendEvent(mWidgetScene, &wsce);@

      Event filter
      @bool UiManager::eventFilter(QObject *target, QEvent *event) {
      if (target == mWidgetView->viewport() && event->type() == QEvent::Paint) {

      QPaintEvent pe = (QPaintEvent)event;

      if(!mUiDirty) {
      redrawRect = pe->rect();
      mUiDirty = true;
      }
      else
      redrawRect = redrawRect.united(pe->rect());
      qDebug() << "paint" << pe->rect() << "->" << redrawRect;

      // can't return true now, it breaks drawing again somehow
      // return true;
      }

      return false;
      }@

      Rendering is obvious
      @mWidgetView->render(&painter, redrawRect, redrawRect);@

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