QGraphicsView sureVisible () и centerOn () - PullRequest
2 голосов
/ 25 мая 2010

Я собираюсь делать панорамирование / масштабирование на QGraphicsView .
Поэтому я прочитал документацию QGraphicsView и вижу некоторые служебные функции, такие как sureVisible () и centerOn () .
Мне кажется, я понимаю, что говорится в документации, но мне не удается написать рабочий пример.
Не могли бы вы написать / предложить мне пример кода, чтобы понять проблему.

1 Ответ

3 голосов
/ 26 мая 2010

Тонизирует представление на определенную величину (например, в вашем представлении mouseMoveEvent()), предполагая, что MyView является подклассом QGraphicsView (весь следующий код был перенесен из Python, я его не тестировал) :

void MyView::moveBy(QPoint &delta) 
{
    QScrollBar *horiz_scroll = horizontalScrollBar();
    QScrollBar *vert_scroll = verticalScrollBar();
    horiz_scroll->setValue(horiz_scroll.value() - delta.x());
    vert_scroll->setValue(vert_scroll.value() - delta.y());
}

Чтобы подогнать прямоугольник, указанный в координатах сцены, путем масштабирования и панорамирования:

void MyView::fit(QRectF &rect)
{
    setSceneRect(rect);
    fitInView(rect, Qt::KeepAspectRatio);
}

Обратите внимание, что если ваша сцена содержит не трансформируемые элементы (с установленным флагом QGraphicsItem::ItemIgnoresTransformations), вам придется предпринять дополнительные шаги, чтобы вычислить их правильную ограничивающую рамку:

/**
 * Compute the bounding box of an item in scene space, handling non 
 * transformable items.
 */
QRectF sceneBbox(QGraphicsItem *item, QGraphicsItemView *view=NULL)
{
    QRectF bbox = item->boundingRect();
    QTransform vp_trans, item_to_vp_trans;

    if (!(item->flags() & QGraphicsItem::ItemIgnoresTransformations)) {
        // Normal item, simply map its bounding box to scene space
        bbox = item->mapRectToScene(bbox);
    } else {
        // Item with the ItemIgnoresTransformations flag, need to compute its
        // bounding box with deviceTransform()
        if (view) {
            vp_trans = view->viewportTransform();
        } else {
            vp_trans = QTransform();
        }
        item_to_vp_trans = item->deviceTransform(vp_trans);
        // Map bbox to viewport space
        bbox = item_to_vp_trans.mapRect(bbox);
        // Map bbox back to scene space
        bbox = vp_trans.inverted().mapRect(bbox);
    }

    return bbox;
}

В этом случае ограничивающий прямоугольник ваших объектов становится зависимым от уровня масштабирования представления, что означает, что иногда MyView::fit() не будет точно соответствовать вашим объектам (например, при подборе выделенных объектов из в значительной степени уменьшенного представления). Быстрое и грязное решение состоит в том, чтобы повторно вызывать MyView::fit() до тех пор, пока ограничивающий прямоугольник естественным образом не "стабилизируется".

...