当图形项目靠在其边框上时,使 QGraphicsScene 更大

Posted

技术标签:

【中文标题】当图形项目靠在其边框上时,使 QGraphicsScene 更大【英文标题】:Making QGraphicsScene bigger when a graphic item is placed against its border 【发布时间】:2010-11-21 10:28:16 【问题描述】:

我创建了一个QGraphicsScene 和一个mouseClickEvent,让用户可以在其中创建蓝色方块。但是我想在将项目放在其边框上时使场景扩大,以便用户永远不会用完图形场景上的空间。

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

【问题讨论】:

【参考方案1】:

我建议执行以下操作:

    使用QGraphicsScene::itemsBoundingRect()获取场景中所有项目的边界矩形。 在该矩形周围添加一些填充,以确保项目的边界不会碰到视图的边缘。 myRect.adjust(-20, -20, 20, 20) 之类的内容就足够了。 使用QGraphicsView::fitInView(myRect, Qt::KeepAspectRatio) 确保拍摄区域在视图的可见范围内。

应该这样做。每当场景中发生变化时,都应该调用此代码。您可以使用 QRectF::intersects() 函数来确定新的矩形是否已放置在视图的边缘。

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

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

希望对您有所帮助。

【讨论】:

+1 以获得明确的答案。但是,如果我不想调整内容大小以适应屏幕并使用滚动条解决方案,该怎么办? 等等,找到了...我必须在图形视图上使用setSceneRect【参考方案2】:

对不起,如果这有点晚了(6 年),但如果有人仍在为此苦苦挣扎或想要另一种方法,我会提供答案。我在派生自 QGraphicsObject 的自定义类中的 mouseReleaseEvent 中实现了这一点。请注意,我使用以下代码初始化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);

【讨论】:

【参考方案3】:

我知道已经很晚了,但是对于在这里寻找 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

解释

    使用self.sceneRect().contains(self.itemBoundingRect)检查itemBoundingRect是否在sceneRect内,如果不在sceneRect内则使用self.setSceneRect()增加sceneRect的大小 (注意:确保添加到之前的 sceneRect 中,如上面的代码所示)。

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

用法

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

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

【讨论】:

以上是关于当图形项目靠在其边框上时,使 QGraphicsScene 更大的主要内容,如果未能解决你的问题,请参考以下文章

仅当我将鼠标悬停在其上时如何使图像出现

当鼠标悬停在边框上时,如何完全禁用调整窗口大小,包括调整大小图标?

当鼠标在图形线或刻度点上时如何显示 LinePlot JPGraph 的值

如何使 NSWindow 中的按钮在工作表上时可点击

C#中,当鼠标移动到按钮上时,按钮边框闪烁,鼠标移开时恢复正常,急急急

如何使边框过渡从左到右(边框出现在悬停时)