Как работает QGraphicsItem:: prepareGeometryChange()?

В соответствии с документами Qt он "Подготавливает элемент для изменения геометрии. Вызовите эту функцию перед изменением ограничивающего прямоугольника элемента, чтобы обновить индекс QGraphicsScene до даты. prepareGeometryChange() вызовет update(), если это необходимо."

Я не понимаю, как QGraphicsItem знает, когда изменяется ограничивающий прямоугольник, и как он знает, когда вызывать update(). Вы когда-нибудь должны были вызвать update() самостоятельно после вызова prepareGeometryChange(), а затем изменить ограничивающий прямоугольник?

Я был бы очень благодарен за понимание того, что похоже на метод ясновидения.

Ответ 1

  • как QGraphicsItem знает, когда изменяется ограничивающий прямоугольник?

Я думаю, вы знаете. Скажем, у вас есть QGraphicsItemGroup, объединяющая несколько дочерних элементов, и вы хотите показывать только одного ребенка за раз. Ограничивающий прямоугольник элемента группы должен быть таким же, как ограничивающий прямоугольник текущего выбранного элемента:

QRectF MyItemGroup::boundingRect() const
{
    QRectF rect;
    if (currentItem_) {
        rect = currentItem_->boundingRect();
    }
    return rect;
}

Предположим, у вас есть способ изменить, какой из них должен быть показан:

void MyItemGroup::setCurrentItem(MyItem * item)
{
    if (list_of_items_.contains(item)) {
        prepareGeometryChange();
        currentItem_ = item;
    }
}

Если вы закомментируете prepareGeometryChange, представление не будет запрашивать снова ограничение ограничителя MyItemGroup, а обновление элемента (вызванное где-то еще) будет связано с неправильным прямоугольником.

  • как он знает, когда вызывать update()?

В соответствии с источниками QGraphicsItem внутри обновления метода prepareGeometry вызывается только в двух случаях:

  • если кто-то подключен к сигналу changed
  • Если сцена не имеет просмотров

подробнее здесь

  • Вы когда-либо должны были вызвать update() самостоятельно после вызова prepareGeometryChange(), а затем изменение ограничивающего прямоугольника?

Я думаю, что ответ - Нет. Помимо вызова update, prepareGeometryChange отмечает как грязную область элемента на сцене, вызывая перерисовку самой области. По моему опыту, этого было достаточно в 100% случаев, поэтому мне не нужно было вызывать update().