QGraphicsView efficient offscreen painting
-
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);@