当图形项目靠边框放置时,使QGraphicsScene更大

时间:2010-11-21 10:28:16

标签: c++ qt qgraphicsview

我创建了QGraphicsScene mouseClickEvent,让用户在其中创建蓝色方块。但是当一个项目放在边框上时,我想让场景变大,这样用户就不会在图形场景上耗尽空间。

在这种情况下,使图形场景更大的最佳方法是什么?

3 个答案:

答案 0 :(得分:4)

我建议做类似以下的事情:

  1. 使用QGraphicsScene::itemsBoundingRect()获取场景中所有项目的边界矩形。
  2. 在该矩形周围添加一些填充,以确保项目的边界不会到达视图的边缘。像myRect.adjust(-20, -20, 20, 20)这样的东西就足够了。
  3. 使用QGraphicsView::fitInView(myRect, Qt::KeepAspectRatio)确保拍摄区域在视图的可见范围内。
  4. 应该这样做。只要场景中发生了某些变化,就应该调用此代码。您可以使用QRectF :: intersects()函数来确定新的rect是否已放置在视图的边缘。

      

    在这种情况下,使图形场景更大的最佳方法是什么?

    GraphicsScene是一个无限坐标系。大多数客户端将使用itemsBoundingRect()来了解场景中项目实际使用了多少空间。如果您已清除场景,则可能需要再次呼叫QGraphicsScene::setSceneRect(QRectF())以“将其缩小”。

    希望有所帮助。

答案 1 :(得分:1)

对不起,如果这有点晚了(6年),但是如果有人仍在努力解决这个问题或者想要另一种方法,我会提供答案。我在mouseReleaseEvent中在QGraphicsObject中实现这个来自{{1 }}。请注意,我使用以下代码初始化QGraphicsScene(1000,1000)的大小。scene->setSceneRect(0,0,1000,1000)。所以我的代码将在这里做。如果项目(项目可拖动)放置在边框上,则该边框将增加。所以这是我的代码:

void MyItem::mouseReleaseEvent(QgraphicsceneMouseEvent* event){
  QRectF tempRect = this->scene()->sceneRect();
  if(this->scenePos().y() < this->scene()->sceneRect().top()){
      tempRect.adjust(0,-200,0,0);
      if(this->scenePos().x() < this->scene()->sceneRect().left()){
          tempRect.adjust(-200,0,0,0);
      }
      else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
        tempRect.adjust(0,0,200,0);
      }
  }
  else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
      tempRect.adjust(0,0,0,200);
      if(this->scenePos().x() < this->scene()->sceneRect().left()){
          tempRect.adjust(-200,0,0,0);
     }
     else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
        tempRect.adjust(0,0,200,0);
     }
 }
 else if(this->scenePos().x() < this->scene()->sceneRect().left()){
      tempRect.adjust(-200,0,0,0);
      if(this->scenePos().y() < this->scene()->sceneRect().top()){
          tempRect.adjust(0,-200,0,0);
      }
      else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
          tempRect.adjust(0,0,0,200);
      }
  }
  else if(this->scenePos().x() + 200> this->scene()->sceneRect().right()){
      tempRect.adjust(0,0,200,0);
      if(this->scenePos().y() < this->scene()->sceneRect().top()){
          tempRect.adjust(0,-200,0,0);
      }
      else if(this->scenePos().y() + 200 > this->scene()->sceneRect().bottom()){
          tempRect.adjust(0,0,0,200);
      }
  }

  this->scene()->setSceneRect(tempRect);

答案 2 :(得分:0)

我知道为时已晚,但对于在这里寻找 python 代码的人来说:

class Scene(QtWidgets.QGraphicsScene):
    def __init__(self):
        super(Scene, self).__init__()
        self.setSceneRect(0, 0, 2000, 2000)

        self.sceneRect().adjust(-20, -20, 20, 20)
        self.old_rect = self.itemsBoundingRect()

    def adjust(self):
        w = self.sceneRect().width()
        h = self.sceneRect().height()
        x = self.sceneRect().x()
        y = self.sceneRect().y()
        adjust_factor = 500
        adjust_factor2 = 300

        smaller = self.is_smaller()
        self.old_rect = self.itemsBoundingRect()

        if not self.sceneRect().contains(self.old_rect):
            self.setSceneRect(-adjust_factor + x, -adjust_factor + y, adjust_factor + w, adjust_factor + h)

        if smaller:
            self.setSceneRect(adjust_factor2 + x, adjust_factor2 + y, abs(adjust_factor2 - w), abs(adjust_factor2 - h))

    def is_smaller(self):

        x = self.old_rect.x()
        y = self.old_rect.y()

        h = self.old_rect.height()
        w = self.old_rect.width()

        if ((x <= self.itemsBoundingRect().x()) and (y <= self.itemsBoundingRect().y())
                and (h > self.itemsBoundingRect().height()) and (w > self.itemsBoundingRect().width())):
            return True

        return False

说明

  1. 使用self.sceneRect().contains(self.itemBoundingRect)检查itemBoundingRect是否在sceneRect内,如果不在sceneRect内则使用self.setSceneRect()增加{ {1}} 个尺寸 (注意:确保你像上面的代码一样添加到之前的sceneRect)。

  2. 如果您还想减小 sceneRect。存储旧的 sceneRect 并与新的 itemBoundingRect 进行比较,如果新的 itemSceneRect 矩形较小,则将大小减小一些(参考上面的代码)。

用法

您可以从您喜欢的任何地方调用 adjust 方法。但是从 adjust 调用 mouseReleaseEvent 方法对我来说效果最好。

*如果您有任何建议或疑问,您可以发表评论。