PDA

View Full Version : Repaint child without having the parent automatically repainted



durbrak
13th September 2007, 16:19
I have a very complex QGraphicsView object and thus I try to keep the number of repaints as small as possible to reduce CPU load.

Now I have a widget ontop of the graphics view. That widget needs to be repainted everytime the mouse pointer moves. The problem is, that this immense repainting causes the graphics view also to be repainted and hence I have a CPU load of 100%.
So I need a way to repaint my widget without the graphics view being repainted automatically too.

I already had some kind of a solution - QWidget::setAttribute(Qt::WA_OpaquePaintEvent) - it really only causes the widget to be repainted and therefore the CPU load is at 0%-1%!
The problem with this solution is, that the background of the widget won't be erased before each paintEvent anymore. This causes my new text to be overlapped with the old text.

So I dunno. I either need a way to "erase" the background before paintEvent or find a way to repaint my widget without notifying its parent :(

Thank you guys for suggestions!

Bitto
13th September 2007, 20:12
So you'd like your QGraphicsView contents to shine through into your widget, and you also want your widget to be able to redraw itself without redrawing the QGV. So if the QGV changes under your widget, then I assume you want the widget to recompose itself on top of the QGV, right?

Have you tried QGraphicsView::render()? Try this. Enable the OpaquePaintEvent flag on your widget. Then call QGraphicsView::render() and then draw your widget contents. Like this (untested code):



void OverlayWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
graphicsView->render(rect(), &painter, geometry());
... do your painting here
}


The render function will draw what's under your widget into your widget. So you're doing your own composition. You can also save your widget's background into a QPixmap to avoid asking QGraphicsView to render it all the time. The QGraphicsView, on its side, can do something like this:



void CustomGraphicsView::paintEvent(QPaintEvent *event)
{
QRegion exposed = event->region();
if (exposed.intersects(overlayWidget.geometry())) {
QPixmap pixmap(overlayWidget.size());
pixmap.fill(0);
QPainter pixmapPainter(&pixmap);
render(overlayWidget.rect(), &pixmapPainter, overlayWidget.geometry());
overlayWidget->updateBackground(pixmap);
}
QGraphicsView::paintEvent(event);
}


The idea being that the view updates the overlaywidget's background, so that the overlay can rerender it without asking the view all the time, and the view basically "pushes" changes to the overlay only when necessary....

durbrak
14th September 2007, 09:39
Thank you Andreas, I'll try this when I get home.

I actually have a map as the QGraphicsView background and inside the GV are items. Now my custom widget, is just a widget itself (not a GV item) positioned on top of the GV. The widget just shows me the geographical coordinates of the mouse pointer mapped to the world-map. So I overrid QGraphicsView::mouseMoveEvent() and there I call QWidget::update() to redraw the geographical coordinates with the new mouse position.

It just seems that when I move around my mouse constantly, the Task Manager shows a CPU usage of 49-50% (I have dual-core). I removed my custom paintEvent and just kept a blank QWidget and kept just calling update(). It seems that QWidget::update() causes the GV to do a repaint, because the GV is underneath the QWidget.

When I use the OpaquePaintEvent flag on my QWidget, everything runs okay: the QWidget redraws itself on every new mouse position and the CPU usage is between 0%-2%. But with this solution the previously painted coordinates won't be removed anymore and thus the QWidget paints the new coordinate text just on top of the old one, and after a couple of moves, the QWidget is almost complete black everywhere (you know, because of a couple of hundred text-paints overlapped).

Bitto
14th September 2007, 12:35
I understand, that seems to be what your first post also described.