Search code examples
qtqt4pyqt4

QGraphicsView level of detail handling


I am working on a visualization SW which uses QGraphicsView and QGraphicsScene (Qt4.8, PyQt). I need LOD (level of detail) handling depending on zoom level. For this I create more QGraphicsScenes and I render the whole scene to each with different LOD level. (There is a QGraphicsScene for each LOD level). I switch between these QGraphicsScenes depending on the zoom level. (QGraphicsView.setScene()). The big problem is that the QGraphicsView's ScrollBars resets their positions when setScene() is called.

Here is a code snippet which tries to restore the ScrollBars values, but it doesn't work:

        hsb = self.horizontalScrollBar()
        vsb = self.verticalScrollBar()
        hv, vv = hsb.value(), vsb.value()
        self.lod = i
        self.setScene(self.scenes[self.lod])
        hsb.setValue(hv)    # this simply doesn't work !!!!
        vsb.setValue(vv)

Any idea to retain the positions of the ScrollBars? Or any idea for efficient LOD handling? I could try to connect the ScrollBar's value changed signals into some custom slots which would disconnect from its own signal than re-set the ScrollBar's value from a saved one. That would be a very lame and ugly solution.


Solution

  • I suggest to use a single scene to manage different level of details. You can get the current level of detail directly inside the QGraphicsItem::paint method and draw the item accordingly.

    Example C++:

    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        qreal levelOfDetail = QStyleOptionGraphicsItem::levelOfDetailFromTransform(painter->worldTransform());
        //draw the item depending on the level of detail
    }
    

    Python

    def paint(self, painter, option, widget):
        levelOfDetail = QStyleOptionGraphicsItem.optionlevelOfDetailFromTransform(painter.worldTransform())
        #draw the item depending on the level of detail
    

    See QStyleOptionGraphicsItem::levelOfDetailFromTransform (for pyqt4 QStyleOptionGraphicsItem.levelOfDetailFromTransform )

    For large scene, with a lot of items, consider to group items. You can check the level of details when the scene transform (or the view transform) changes and show/hide the group of items. See QGraphicsItemGroup.