Получить видимый прямоугольник QGraphicsView? - PullRequest
11 голосов
/ 31 августа 2009

Я тяну свои волосы с этим часами. Здесь есть нить , но, похоже, ничего не работает. QGraphicsView :: rect () вернет ширину и высоту, но значения left и top установлены неправильно (всегда 0 - игнорируя прокручиваемую величину). Я хочу это в координатах сцены, но это должно быть достаточно легко для перевода из любой системы. Я понятия не имею, что horizontalScrollBar()->value() и Верт возвращаются ... кажется бессмысленным бредом.


@ fabrizioM

// created here
void EditorWindow::createScene() {
    m_scene = new EditorScene(this);
    m_view = new EditorView(m_scene);
    setCentralWidget(m_view);
    connect(m_scene, SIGNAL(mousePosChanged(QPointF)), this, SLOT(mousePosChanged(QPointF)));
}

/// with this constructor
EditorView::EditorView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent) {
    setRenderHint(QPainter::Antialiasing);
    setCacheMode(QGraphicsView::CacheBackground);
    setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    setDragMode(QGraphicsView::NoDrag);
    scale(1.0, -1.0); // flip coordinate system so that y increases upwards
    fitInView(-5, -5, 10, 10, Qt::KeepAspectRatio);
    setInteractive(true);
    setBackgroundBrush(QBrush(QColor(232,232,232), Qt::DiagCrossPattern));
}

Ответы [ 6 ]

22 голосов
/ 23 января 2011

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

graphicsView->mapToScene(graphicsView->viewport()->geometry()).boundingRect()

Bye, Marcel

6 голосов
/ 31 августа 2009

Nevermind. Придумал это, которое, кажется, работает.

QRectF EditorView::visibleRect() {
    QPointF tl(horizontalScrollBar()->value(), verticalScrollBar()->value());
    QPointF br = tl + viewport()->rect().bottomRight();
    QMatrix mat = matrix().inverted();
    return mat.mapRect(QRectF(tl,br));
}
3 голосов
/ 01 июня 2012

Следующая реализация вернула мне лучшие результаты:

QRectF getVisibleRect( QGraphicsView * view )
{
    QPointF A = view->mapToScene( QPoint(0, 0) ); 
    QPointF B = view->mapToScene( QPoint( 
        view->viewport()->width(), 
        view->viewport()->height() ));
    return QRectF( A, B );
}

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

view->mapToScene( view->viewport()->geometry() )

возвращает QPolygonF (НЕ QRectF), который является видимым прямоугольником в координатах сцены. Кстати, QPolygonF имеет функцию-член boundingRect(), которая не возвращает правильно видимый прямоугольник вида, но может быть полезна в любом случае.

3 голосов
/ 29 июля 2010

вот возможное решение (без понятия, является ли это предполагаемым)

QRectF XXX::getCurrrentlyVisibleRegion() const
{
        //to receive the currently visible area, map the widgets bounds to the scene

        QPointF topLeft = mapToScene (0, 0);
        QPointF bottomRight = mapToScene (this->width(), this->height());

        return QRectF (topLeft, bottomRight);
}

НТН, Бернхард

2 голосов
/ 29 сентября 2009

Вы можете сделать то, что вы сделали, или использовать функции mapToScene (). Вы не можете рассчитывать на то, что результирующий «прямоугольник» сцены будет прямоугольником, потому что сцена может быть повернута или сдвинута в виде, что приведет к общему многоугольнику при отображении на сцену.

Если ваше приложение никогда не делает такие вещи, конечно, вы можете предположить, что прямоугольник всегда уместен.

0 голосов
/ 06 сентября 2009

Звучит так, как будто вам нужен прямоугольник сцены. Метод ::rect() унаследован от QWidget. См:

http://doc.qt.io/qt-5/qgraphicsview.html#sceneRect-prop

...