问题
Is there a (quick?) way to render only a subset of GraphicsScene items according to View zoom level? I'm having a big scene with many grid lines and i want to hide/show some of them, when the zoom changes to avoid the 'grid completely fills the scene'-effect.
Grid lines are drawn using addLine method of GraphicsScene.
P.S. Maybe, the easiest way is to draw grid somewhere else (on view or smth like that), because logically they aren't a part of my scene, they are only guide-lines? But i don't know which way is more effective.
回答1:
It's not advised to create the grid like that because you will be making many objects that will affect the scenes BSP tree, so it will get slow quickly. It will also make having an LOD zoom like you describe more difficult.
I would overwrite QGraphicsView::drawBackground(QPainter* painter, const QRectF& rect)
, and use the view's bounds in scene coordinates to calculate how many grid lines you want and where they are. Then just paint as normal painting operation.
You will have to set the update mode to QGraphicsView::FullViewportUpdate
otherwise you will get artefacts in the grid render.
回答2:
For grid lines I believe the most common approach is to draw them in the QGraphicsScene::drawBackground()
method. So you would have to subclass QGraphicsScene and override that method. That is what I do in one of my applications and it works very nicely.
I also have some variables zoomX
and zoomY
in my QGraphicsScene subclass. I set them whenever the view's scale is changed. Then in my drawBackground()
method I check whether or not the zoom is appropriate, and if so, I draw the lines, otherwise I don't.
回答3:
You will definitely need to subclass the stock QGraphicsItem subclasses (and thus abandon the convenience of addLine()
).
In the paint()
method of the QGraphicsLineItem subclass, you can try to translate the line coordinates into the coordinate system of the view (using the transform in the QPainter
instance given to paint()
). Then you can estimate the physical length of the line (physical as in: length in pixels on the view), and abort the painting if the lines are too short.
Be warned though that doing so many coordinate calculations will probably make everything very slow.
Edit: The better way might be to implement an entirely new QGraphicsItem which draws the grid at once. This saves quite some overhead on the QGraphicsScene level, compared to maintaining hundreds of line items.
来源:https://stackoverflow.com/questions/12477082/render-qgraphicsscene-according-to-zoom-level