获取 QGraphicsView 的可见矩形?

发布于 2024-08-02 22:23:16 字数 1309 浏览 12 评论 0 原文

我已经用这个把头发拔了好几个小时了。有一个线程 这里 关于它,但似乎没有任何效果。 QGraphicsView::rect() 将返回宽度和高度,但 lefttop 值未正确设置(始终为 0 - 忽略滚动量)。我希望它处于场景坐标中,但它应该很容易从任何系统进行转换。我不知道 horizo​​ntalScrollBar()->value() 和 vert 返回什么......似乎是毫无意义的胡言乱语。


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

I've been pulling my hair out with this one for hours. There's a thread here about it, but nothing seems to be working. QGraphicsView::rect() will return the width and height, but the left and top values aren't set properly (always 0 -- ignoring the scrolled amount). I want it in scene coordinates, but it should be easy enough to translate from any system. I have no idea what horizontalScrollBar()->value() and vert are returning...seems to be meaningless jibberish.


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

墨小墨 2024-08-09 22:23:16

只需使用视图将基于像素的视口矩形映射到场景即可:

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

再见,
马塞尔

Just map the pixel-based viewport rectangle to the scene using the view:

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

Bye,
Marcel

下壹個目標 2024-08-09 22:23:16

没关系。想出了这个,这似乎有效。

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

Nevermind. Came up with this, which seems to work.

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));
}
寂寞清仓 2024-08-09 22:23:16

以下实现为我返回了最好的结果:

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(),它不会返回视图的正确可见矩形,但无论如何可能很有用。

The following implementation returned the best results for me:

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

This works still really well when scrollbars appear. This only works properly if the view does not display the scene rotated or sheared. If the view is rotated or sheared, then the visible rectangle is not axis parallel in the scene coordinate system. In this case

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

returns a QPolygonF (NOT a QRectF) which is the visible rectangle in scene coordinates. By the way, QPolygonF has a member function boundingRect() which does not return the properly visible rectangle of the view, but might be useful anyways.

梦幻的心爱 2024-08-09 22:23:16
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);
}
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);
}
冷…雨湿花 2024-08-09 22:23:16

您可以执行您已完成的操作,或使用 mapToScene() 函数。但是,您不能指望生成的场景“矩形”是矩形,因为场景可能在视图中旋转或剪切,从而在映射到场景时产生一般多边形。

当然,如果您的应用程序从不执行此类操作,您可以随意假设矩形始终合适。

You can do what you've done, or use the mapToScene() functions. You can't count on the resulting scene "rectangle" being a rectangle, however, because the scene might be rotated or sheared in the view, resulting in a general polygon when mapped to the scene.

If your application never does such things, of course, you're free to assume that a rectangle is always appropriate.

纵山崖 2024-08-09 22:23:16

@mpen 的 Qt5/Qt6 版本解决方案:

QRectF EditorView::visibleRect() {
    const QRect viewportRect(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), viewport()->size());
    const auto mat = transform().inverted();
    return mat.mapRect(viewportRect);
}

Qt5/Qt6 version of the solution by @mpen:

QRectF EditorView::visibleRect() {
    const QRect viewportRect(QPoint(horizontalScrollBar()->value(), verticalScrollBar()->value()), viewport()->size());
    const auto mat = transform().inverted();
    return mat.mapRect(viewportRect);
}
仙气飘飘 2024-08-09 22:23:16

听起来你想要的是场景矩形。 ::rect() 方法继承自 QWidget。请参阅:

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

It sounds like what you want is the scene rectangle. The ::rect() method is inherited from QWidget. See:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文