Создание функции автопрокрутки в QGraphicsView

у меня есть QGraphicsView и QGraphicsScene, В зависимости от пользовательского ввода некоторые QGraphicsItem может быть размещен на сцене. Этот предмет можно выбирать и перемещать.

Когда сцена больше, чем появляются полосы прокрутки вида (они устанавливаются так, чтобы показываться при необходимости).

Когда элемент перемещается пользователем к краю вида, ширина / высота сцены соответственно растягиваются — я делаю сцену больше.

Вопрос в том Как заставить полосы прокрутки прокручивать сцену, когда элемент находится около границы вида? Особенность я считаю распространенной в любом графическом редакторе. в MouseMoveEvent Я делаю сцену больше, заставляю ползунки двигаться и соответственно обновляю видимый прямоугольник.

Это не работает, как задумано. Даже при том, что свитки приспосабливаются к новому размеру сцены, нет плавного движения в представлении. Есть ли лучший способ сделать это?

Некоторые объяснения:

    itemUnderCursor = currently slected QGraphicsItem
qgv = QGraphicsView

Фрагмент кода:

    // 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);
}

Я делаю то же самое для верхней и нижней границы QGraphicsView,

2

Решение

Похоже, что моя предыдущая попытка была ужасно сложной, хотя решение на самом деле очень простое.

Вместо предыдущего кода достаточно было написать:

qgv->ensureVisible(itemUnderCursor);

и убедитесь, что sceneRect() не будет установлен с каким-либо значением, а оставлен для обработки самой сценой.

Это позволило сцене автоматически настроить свой размер в соответствии с элементами на ней и заставило полосы прокрутки следовать за движущимся элементом, когда он находится за пределами видимого прямоугольника. QGraphicsView,

6

Другие решения

Других решений пока нет …