【问题标题】:Get visible rectangle of QGraphicsView?获取 QGraphicsView 的可见矩形?
【发布时间】:2018-11-04 04:56:05
【问题描述】:

我已经用这个把头发拉了好几个小时了。有一个关于它的线程here,但似乎没有任何效果。 QGraphicsView::rect() 将返回宽度和高度,但 lefttop 值设置不正确(始终为 0 - 忽略滚动量)。我希望它在场景坐标中,但它应该很容易从任何系统转换。我不知道 horizontalScrollBar()->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));
}

【问题讨论】:

  • 从头开始......滚动条值是相对于......好吧它不可能是 sceneRect() 因为那些是浮动......但类似的东西。
  • 可能是你如何构造 QGraphicsView,有源代码 sn-p 吗?
  • 我不确定您到底想要什么代码。我如何构造它并不重要......得到可见的矩形应该完全相同。

标签: c++ qt qgraphicsview


【解决方案1】:

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

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

再见, 马塞尔

【讨论】:

  • 使用graphicsView->rect()而不是graphicsView->viewport()->geometry()可能会更短。
  • @Sharpie viewport() 是相关的,如果它周围有边框(或可见的滚动条)。
【解决方案2】:

没关系。想出了这个,这似乎可行。

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】:

    以下实现对我来说返回了最好的结果:

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

    【讨论】:

      【解决方案4】:

      这是一个可能的解决方案(不知道这是否是预期的解决方案)

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

      HTH, 伯恩哈德

      【讨论】:

      • 在 Qt 4.7.4 中,这里的大多数答案都不起作用。视图坐标 (0, 0) 似乎并不总是位于可见区域的左上角。相反,视图坐标系本身由滚动条移动。但是马克的方法有效! (对我来说)
      【解决方案5】:

      你可以做你已经做过的事情,或者使用 mapToScene() 函数。但是,您不能指望生成的场景“矩形”是矩形,因为场景可能会在视图中旋转或剪切,从而在映射到场景时产生一般多边形。

      如果您的应用程序从不做这些事情,当然,您可以随意假设矩形总是合适的。

      【讨论】:

      • 什么映射到场景中?除了滚动条,我似乎无法从其他任何地方获得所需的信息。
      【解决方案6】:

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

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

      【讨论】:

      • 您阅读说明了吗? “场景矩形定义了场景的范围,在视图的情况下,这意味着您可以使用滚动条导航的场景区域。” sceneRect 返回整个场景,而不仅仅是当前可见的区域(场景的一部分)。
      • 直接从文档中提取; “此属性包含此视图可视化的场景区域。”。这就是你想要的对吗?您还可以使用 mapTo 和 mapFrom 在坐标系之间进行转换。
      • 文档不清楚。 “可视化”是什么意思?它是指您正在使用的场景区域还是只是现在绘制的区域?如果你有一个可以滚动的巨大场景,那么这个词的选择是模棱两可的。我也很困惑。看起来这是整个场景,而不仅仅是您现在可以在视图中看到的区域。
      • 如果您继续阅读,(当前)文档很清楚:“场景矩形定义了场景的范围,在视图的情况下,这意味着您可以使用滚动条。”
      猜你喜欢
      • 2011-12-28
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      相关资源
      最近更新 更多