Увеличение размера QGraphicsScene при размещении графического элемента у его границы

Я сделал QGraphicsScene с mouseClickEvent, что позволяет пользователю создавать синие квадраты внутри него. Но я хочу, чтобы сцена увеличивалась, когда элемент размещается у ее границы, чтобы у пользователя никогда не заканчивалось место на графической сцене.

Как лучше всего увеличить графическую сцену в этом случае?


person Pieter    schedule 21.11.2010    source источник


Ответы (3)


Я предлагаю сделать что-то вроде следующего:

  1. Получите ограничивающий прямоугольник всех элементов сцены, используя QGraphicsScene::itemsBoundingRect().
  2. Добавьте отступы вокруг этого прямоугольника, чтобы границы элементов не попадали на край представления. Что-то вроде myRect.adjust(-20, -20, 20, 20) должно быть достаточно.
  3. Используйте QGraphicsView::fitInView(myRect, Qt::KeepAspectRatio), чтобы убедиться, что снятая область находится в видимых границах вида.

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

Как лучше всего увеличить графическую сцену в этом случае?

GraphicsScene — это бесконечная система координат. Большинство клиентов будут использовать itemsBoundingRect(), чтобы получить представление о том, сколько места на самом деле используется элементами в сцене. Если вы очистили сцену, вы можете вызвать QGraphicsScene::setSceneRect(QRectF()), чтобы снова "сделать ее меньше".

Надеюсь, это поможет.

person BastiBen    schedule 21.11.2010
comment
+1 за четкий ответ. Но что, если я не хочу, чтобы содержимое изменялось по размеру экрана, а вместо этого использовало полосу прокрутки? - person Pieter; 22.11.2010
comment
Подождите, нашел... Я должен использовать setSceneRect в графическом представлении. - person Pieter; 22.11.2010

извините, если это немного поздно (6 лет), но я дам ответ, если кто-то все еще борется с этим или хочет другой подход. Я реализую это в mouseReleaseEvent в пользовательском классе, производном от QGraphicsObject. Обратите внимание, что я инициализирую размер моего 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);
person nafizfarhan    schedule 21.02.2017

Я знаю, что уже поздно, но для тех, кто ищет здесь код 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(), чтобы увеличить размер sceneRect (Примечание: убедитесь, что вы добавили к предыдущей сценеRect, как показано в приведенном выше коде).

  2. Если вы также хотите уменьшить sceneRect. Сохраните старый itemBoundingRect и сравните его с новым, если новый прямоугольник itemSceneRect меньше, уменьшите размер на некоторый коэффициент (см. приведенный выше код).

Использование:

вы можете вызывать метод adjust из любого места. Но вызов метода adjust из mouseReleaseEvent сработал для меня лучше всего.

* Если у вас есть какие-либо предложения или вопросы, вы можете оставить комментарий.

person JacksonPro    schedule 22.12.2020