Game Programming using Qt 5 Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Optimizing the view

Since we are talking about the item's paint() function, let's touch on something related. By default, the view ensures that the painter state is saved before calling the item's paint function and that the state gets restored afterward. This will end up saving and restoring the painter state, say 50 times, if you have a scene with 50 items. However, you can disable this behavior by calling setOptimizationFlag(DontSavePainterState, true) on the view. If you do this, it is now your responsibility to ensure that any paint() function that changes the state of the painter (including pen, brush, transformation, and many other properties) must restore the previous state at the end. If you prevent automatic saving and restoring, keep in mind that now the standard items will alter the painter state. So if you use both standard and custom items, either stay with the default behavior or set DontSavePainterState, but then set up the pen and brush with a default value in each item's paint function.

Another flag that can be used with setOptimizationFlag() is DontAdjustForAntialiasing. By default, the view adjusts the painting area of each item by two pixels in all directions. This is useful because when one paints anti-aliased, one easily draws outside the bounding rectangle. Enable that optimization if you do not paint anti-aliased or if you are sure that your painting will stay inside the bounding rectangle. If you enable this flag and spot painting artifacts on the view, you haven't respected the item's bounding rectangle!

As a further optimization, you can define how the view should update its viewport when the scene changes. You can set the different modes with setViewportUpdateMode(). By default (QGraphicsView::MinimalViewportUpdate), the view tries to determine only those areas that need an update and repaints only these. However, sometimes it is more time-consuming to find all the areas that need a redraw than to just paint the entire viewport. This applies if you have many small updates. Then, QGraphicsView::FullViewportUpdate is the better choice since it simply repaints the whole viewport. A kind of combination of the last two modes is QGraphicsView::BoundingRectViewportUpdate. In this mode, Qt detects all areas that need a redraw, and then it redraws a rectangle of the viewport that covers all areas affected by the change. If the optimal update mode changes over time, you can tell Qt to determine the best mode using QGraphicsView::SmartViewportUpdate. The view then tries to find the best update mode.