QGraphicsItem::prepareGeometryChange() 是如何工作的?

15
根据Qt文档,prepareGeometryChange()函数“为几何变换准备项。在更改项的边界矩形以保持QGraphicsScene索引最新之前,请调用此函数。如果需要,prepareGeometryChange()将调用update()函数。”
我不理解的是QGraphicsItem如何知道边界矩形何时发生了变化,以及它如何知道何时调用update()函数。在调用prepareGeometryChange()并更改边界矩形后,是否需要自己调用update()函数?
我非常感谢对这个看起来有先知能力的方法的深入了解。
1个回答

21
  • 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方法内仅在两种情况下调用update:

  1. 如果有人连接到changed信号
  2. 如果场景没有视图

更多详细信息请参见此处

  • 在调用prepareGeometryChange()并更改边界矩形后,您是否应该自己调用update()?

我认为答案是否定的。除了调用update之外,prepareGeometryChange还会将场景上的项目区域标记为脏区域,从而导致该区域的重新绘制。根据我的经验,在100%的情况下这就足够了,因此我不需要调用update()。


1
更一般地说,你可以明确指出每当::boundingRect()计算的输入发生变化时应该调用它。不过你的例子是正确的。 - azf
再次感谢,抱歉耽搁了! - Anthony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接