在QGraphicsView中创建自动滚动功能

Mat*_*ski 3 c++ qt qgraphicsview autoscroll qgraphicsscene

我有一个QGraphicsView和一个QGraphicsScene.根据用户输入,QGraphicsItem可以将一些放置在场景上.此项目既可选择又可移动.

当场景大于视图滚动条时(它们设置为在必要时显示).

当用户在视图边缘附近移动项目时,场景宽度/高度会相应地拉伸 - 我使场景变大.

问题是当项目靠近视图边界时,如何强制滚动条与场景一起滚动?我觉得在任何图形编辑器中都很常见.在MouseMoveEvent场景中我使场景变大,强制滑块移动并相应地更新可见矩形.

这不符合预期.即使认为卷轴正在调整到新的场景大小,视图中也没有平滑的移动.这样做有更好的方法吗?

一些解释:

    itemUnderCursor = currently slected QGraphicsItem
    qgv = QGraphicsView
Run Code Online (Sandbox Code Playgroud)

代码段:

    // check if item is near the border
    QPointF point = itemUnderCursor->mapToScene(itemUnderCursor->boundingRect().topLeft());
    double delta = 0;

    if(point.x() < visibleRect.left())
    {
        // prevent from drawing outside the scene
        itemUnderCursor->setPos(visibleRect.left(), itemUnderCursor->scenePos().y());

        if(event->scenePos().x() < oldMousePos.x()-3)
        {
            // stretch the scene
            if(qgv->horizontalScrollBar()->value() <= 0)
                setSceneRect(QRectF(QPointF(sceneRect().x() - 3, sceneRect().y()), sceneRect().bottomRight()));
            /*
             * disable signals from DrawingArea in order to avoid
             * recursive calls of mouseMoveEvent then enabling them
             * back to handle the rest of events
             */
            this->blockSignals(true);
            delta = point.x() - originalRect.left();
            qgv->horizontalScrollBar()->setValue(hScrollOriginalValue + delta);
        }
        oldMousePos = event->scenePos();
        this->blockSignals(false);

        // update the visible rectangle
        visibleRect = getVisibleRect(qgv);
    }

    if(point.x() + itemUnderCursor->boundingRect().width() > visibleRect.right())
    {
        // prevent from drawing outside the scene
        itemUnderCursor->setPos(visibleRect.right() - itemUnderCursor->boundingRect().width(), itemUnderCursor->scenePos().y());
        if(event->scenePos().x() > oldMousePos.x()+3)
        {
            // stretch the scene
            if(qgv->horizontalScrollBar()->value() >= 0)
                setSceneRect(QRectF(sceneRect().topLeft(), QPointF(sceneRect().bottomRight().x() + 3, sceneRect().bottomRight().y())));

            /*
             * disable signals from DrawingArea in order to avoid
             * recursive calls of mouseMoveEvent then enabling them
             * back to handle the rest of events
             */
           delta = point.x() + itemUnderCursor->boundingRect().width() - originalRect.right();
           this->blockSignals(true);
           qgv->horizontalScrollBar()->setValue(hScrollOriginalValue + delta);
        }
        oldMousePos = event->scenePos();
        this->blockSignals(false);

        // update the visible rectangle
        visibleRect = getVisibleRect(qgv);
    }
Run Code Online (Sandbox Code Playgroud)

我正在做同样的顶部和底部边界QGraphicsView.

Mat*_*ski 7

看来我之前的尝试非常复杂,而解决方案实际上非常简单.

而不是以前的代码,它写得足够​​:

qgv->ensureVisible(itemUnderCursor);
Run Code Online (Sandbox Code Playgroud)

并确保sceneRect()不会设置任何值,而是由场景本身处理.

这允许场景根据其上的项目自动调整其大小,并强制滚动条在可见矩形外部跟随移动项目QGraphicsView.