GraphicsView: Artifacts after reducing boundingRect size - scene()->update() does nothing
-
I have a scene which consists of a background, two grids (vertical and horizontal) and a line plot. Each is a separate, custom QGraphicsItem.
I can scale the whole X-axis. When that happens, I call "prepareGeometryChange" and re-calculate the boundingRect for the line plot.
Now, when I change the scaling so the line plot becomes more narrow, a part of the scene that was previously covered by the line plot should now only display background and grid. However, I see the remains of the "old" line plot painting all over the place.
I have checked that the boundingRect has the correct size, by replacing the paint code with (basically) painter->drawRect(boundingRect()); The size is exactly as expected, before and after scaling the x-axis.
I have double-checked that prepareGeometryChange() is called before I actually recalculate the boundingRect, so that it would get the old boundingRect if needed.
And now it gets strange: I have tried to force repainting by calling either linePlot->update(); (before or after the change to the boundingRect), or even by calling scene->update() or scene->invalidate()
Nothing! These calls do not seem to have any effect!However, cover the window with something else, and show it again, and everything is displayed as it should be.
I also checked that none of the items use caching (setCachingMode).Any ideas what could prevent a scene()->update() from repainting the scene?
-
Hi,
That's maybe related to the viewport update mode.
-
@SGaist said in GraphicsView: Artifacts after reducing boundingRect size - scene()->update() does nothing:
Hi,
That's maybe related to the viewport update mode.
Good hint! Viewport update modes Minimal and Smart show the incorrect repaint, while viewport modes Full and BoundingRect display correctly.
The documentation on the modes is a bit thin...why would Minimal and Smart conclude that an area does not need to redraw, even though I explicitly call update() on the item?
-
Sorry, I can't answer that one, a look at the algorithm used might give you more information about that.
-
@SGaist said in GraphicsView: Artifacts after reducing boundingRect size - scene()->update() does nothing:
Sorry, I can't answer that one, a look at the algorithm used might give you more information about that.
I have tried, but debugging this part of code is not easily done, because switching between debugger and applications triggers invalidates and repaints.
Also, watching regions in the debugger is not easily done... -
Do you make sure to paint inside the bounding rect? If you have, let's say, a 200x200 rect that you draw with 2p brush width, the bounding rect is actually 202x202.
Usually this means, if you want to draw a 200x200 rect with 2p brush width, you should draw a 198x198 rect to keep everything inside the 200x200 bounding rect.
-
@BjornW said in GraphicsView: Artifacts after reducing boundingRect size - scene()->update() does nothing:
Do you make sure to paint inside the bounding rect? If you have, let's say, a 200x200 rect that you draw with 2p brush width, the bounding rect is actually 202x202.
Usually this means, if you want to draw a 200x200 rect with 2p brush width, you should draw a 198x198 rect to keep everything inside the 200x200 bounding rect.
I know the artifacts I get when I do this mistake: A thin border around the area of the old bounding rect. However, in my case the artifacts practically fill the old bounding rect.
Also, all my pens are hairline (1 px cosmetic), and GraphicsView normally takes that one pixel around the boundingRect into account, if memory serves me. -
For one thing, here is how it looks with artefacts:
Screenshot
Each of the colorful rectangles is a GraphicsItem. The "old" boundingRect has a width of 981 px. The "new" boundingRect is half as wide, and slightly to the left of the center. All colored areas above and below the dashed line should be black with a gray grid.The paint code is simple. This is not the original code, but sufficient to cause the effect.
painter->setPen(Qt::NoPen); painter->setBrush(QBrush(m_LinePen.color())); painter->drawRect(boundingRect());
-
By calling "prepareGeometryChange()" and then changing the fundamental parameters that are used in my overload of boundingRect()