【Qt系列】QGraphicsItem状态改变函数itemChange之pos改变发送通知示例

当我们需要定义自己的类时候,可以重定义itemChange函数。如果需要item状态发生改变时发送通知,需要开启对应的功能。在构造函数当中引用setFlag(ItemSendsGeometryChanges);设置ItemSendsGeometryChange标志位。

Node::Node()
{
    setFlag(ItemIsMovable);				//提供拖拽功能
    setFlag(ItemSendsGeometryChanges);	//打开通知
    //setCacheMode(DeviceCoordinateCache);
    //setZValue(-1);
}

关于setFlag函数的说明可参照【Qt系列】Graphics View框架下实现自定义item类的拖动,在自定义Item类的声明重定义函数itemChange函数,直接复制粘贴就好。

protected:
    QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;

如代码所示,该函数有两个输入参数,一个是GraphicsItemChange,一个是QVariant。

GraphicsItemChange

这是QGraphicsItem类的枚举。此枚举描述了 QGraphicsItem::itemChange() 通知的状态更改。通知在状态更改时发送,在某些情况下,可以进行调整(有关详细信息,请参阅每个更改的文档)。

注意:在 itemChange() 中调用 QGraphicsItem 本身的函数时要小心,因为某些函数调用可能会导致不需要的递归。例如,您不能在 ItemPositionChange 通知时调用 itemChange() 中的 setPos(),因为 setPos() 函数将再次调用 itemChange(ItemPositionChange)。相反,您可以从 itemChange() 返回新的、调整后的位置。

以下为该枚举的取值。

常量描述
QGraphicsItem::ItemEnabledChange项目的启用状态发生更改。如果该项目当前处于启用状态,它将被禁用,反之亦然。值参数是新启用的状态(即 true 或 false)。不要在 itemChange() 中调用 setEnabled(),因为此通知已传递。相反,您可以从 itemChange() 返回新状态。
QGraphicsItem::ItemEnabledHasChanged项目的启用状态已更改。值参数是新启用的状态(即 true 或 false)。不要在 itemChange() 中调用 setEnabled(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemMatrixChange项目的仿射转换矩阵正在更改。此值已过时;您可以改用 ItemTransformChange。
QGraphicsItem::ItemPositionChange项目的位置发生变化。如果启用了 ItemSendsGeometryChanges 标志,并且当项目的本地位置相对于其父级(即,由于调用 setPos() 或 moveBy())而发生更改时,将发送此通知。值参数是新位置(即 QPointF)。您可以调用 pos() 来获取原始位置。不要在 itemChange() 中调用 setPos() 或 moveBy() 作为此通知的传递;相反,您可以从 itemChange() 返回新的、调整后的位置。在此通知之后,如果位置发生更改,QGraphicsItem 会立即发送 ItemPosition 已更改通知。
QGraphicsItem::ItemPositionHasChanged项目的位置已更改。如果启用了 ItemSendsGeometryChanges 标志,并且在项目的本地位置(相对于其父级)发生更改后,将发送此通知。value 参数是新位置(与 pos() 相同),QGraphicsItem 忽略此通知的返回值(即只读通知)。
QGraphicsItem::ItemTransformChange项目的转换矩阵将发生更改。如果启用了 ItemSendsGeometryChanges 标志,并且当项目的本地转换矩阵发生更改(即,作为调用 setTransform() 的结果)时,将发送此通知。值参数是新矩阵(即 QTransform);要获取旧矩阵,请调用 transform()。在传递此通知时,不要调用 setTransform() 或在 itemChange() 中设置任何转换属性;相反,您可以从 itemChange() 返回新矩阵。如果更改转换属性,则不会发送此通知。
QGraphicsItem::ItemTransformHasChanged项的转换矩阵已更改,因为调用了 setTransform,或者更改了其中一个转换属性。如果启用了 ItemSendsGeometryChanges 标志,并且在项目的本地转换矩阵发生更改后,将发送此通知。value 参数是新矩阵(与 transform() 相同),QGraphicsItem 忽略此通知的返回值(即只读通知)。
QGraphicsItem::ItemRotationChange项的旋转属性将发生更改。如果启用了 ItemSendsGeometryChanges 标志,并且当项目的旋转属性发生更改(即,作为调用 setRotation() 的结果)时,将发送此通知。值参数是新的旋转(即双精度);要获取旧的旋转,请调用 rotation()。不要在 itemChange() 中调用 setRotation() 作为此通知的传递;相反,您可以从 itemChange() 返回新的旋转。
QGraphicsItem::ItemRotationHasChanged项的旋转属性已更改。如果启用了 ItemSendsGeometryChanges 标志,并且在项目的旋转属性发生更改后,将发送此通知。value 参数是新的旋转(即双精度),QGraphicsItem 忽略此通知的返回值(即只读通知)。不要在 itemChange() 中调用 setRotation(),因为此通知已传递。
QGraphicsItem::ItemScaleChange项目的比例属性将发生更改。如果启用了 ItemSendsGeometryChanges 标志,并且当项目的 scale 属性发生更改(即,作为调用 setScale() 的结果),则会发送此通知。值参数是新刻度(即双精度);要获取旧的刻度,请调用 scale()。不要在 itemChange() 中调用 setScale(),因为此通知已送达;相反,您可以从 itemChange() 返回新比例。
QGraphicsItem::ItemScaleHasChanged项目的比例属性已更改。如果启用了 ItemSendsGeometryChanges 标志,并且在项目的 scale 属性发生更改后,将发送此通知。value 参数是新刻度(即双精度),QGraphicsItem 忽略此通知的返回值(即只读通知)。不要在 itemChange() 中调用 setScale(), 因为此通知已传递。
QGraphicsItem::ItemTransformOriginPointChange项的变换原点属性发生更改。如果启用了 ItemSendsGeometryChanges 标志,并且当项目的转换源点属性发生更改(即,作为调用 setTransformOriginPoint() 的结果),则会发送此通知。值参数是新的原点(即 QPointF);若要获取旧的原点,请调用 transformOriginPoint()。不要在 itemChange() 中调用 setTransformOriginPoint() 作为此通知的传递;相反,您可以从 itemChange() 返回新的转换原点。
QGraphicsItem::ItemTransformOriginPointHasChanged项的变换原点属性已更改。如果启用了 ItemSendsGeometryChanges 标志,并且在项目的转换源点属性发生更改后,将发送此通知。value 参数是新的源点(即 QPointF),QGraphicsItem 忽略此通知的返回值(即只读通知)。不要在传递此通知时在 itemChange() 中调用 setTransformOriginPoint()。
QGraphicsItem::ItemSelectedChange项目的选定状态将发生更改。如果当前选择了该项目,它将变为未选中状态,反之亦然。值参数是新选定的状态(即 true 或 false)。不要在 itemChange() 中调用 setSelected()作为此通知的传递;相反,您可以从 itemChange() 返回新的选定状态。
QGraphicsItem::ItemSelectedHasChanged项目的选定状态已更改。值参数是新选定的状态(即 true 或 false)。不要在 itemChange() 中调用 setSelected(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemVisibleChange项目的可见状态发生更改。如果该项目目前可见,它将变得不可见,反之亦然。值参数是新的可见状态(即,真或假)。不要在 itemChange() 中调用 setVisible(),因为此通知已送达;相反,您可以从 itemChange() 返回新的可见状态。
QGraphicsItem::ItemVisibleHasChanged项目的可见状态已更改。值参数是新的可见状态(即,真或假)。不要在 itemChange() 中调用 setVisible(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemParentChange项目的父项将发生更改。值参数是新的父项(即 QGraphicsItem 指针)。不要在 itemChange() 中调用 setParentItem() 作为此通知的传递;相反,您可以从 itemChange() 返回新的父级。
QGraphicsItem::ItemParentHasChanged项目的父项已更改。值参数是新的父级(即指向 QGraphicsItem 的指针)。不要在 itemChange() 中调用 setParentItem() 作为此通知的传递。返回值将被忽略。
QGraphicsItem::ItemChildAddedChange一个孩子将添加到此项目中。值参数是新的子项(即 QGraphicsItem 指针)。在传递此通知时,不要将此项目传递给任何项目的 setParentItem() 函数。返回值未使用;您无法调整此通知中的任何内容。请注意,发送此通知时,新子项可能未完全构造;在子项上调用纯虚拟函数可能会导致崩溃。
QGraphicsItem::ItemChildRemovedChange将从此项目中删除一个孩子。值参数是要删除的子项(即 QGraphicsItem 指针)。返回值未使用;您无法调整此通知中的任何内容。
QGraphicsItem::ItemSceneChange项目将移动到新场景。当项目添加到其初始场景以及移除项目时,也会发送此通知。项目的 scene() 是旧场景(如果项目尚未添加到场景中,则为 0)。值参数是新场景(即 QGraphicsScene 指针),如果从场景中删除了该项目,则为空指针。不要通过将此项目传递给 QGraphicsScene::addItem() 来覆盖此更改,因为此通知已送达;相反,您可以从 itemChange() 返回新场景。请谨慎使用此功能;反对场景更改可能会很快导致不必要的递归。
QGraphicsItem::ItemSceneHasChanged项目的场景已更改。项目的 scene() 是新场景。当项目添加到其初始场景以及移除项目时,也会发送此通知。值参数是新场景(即指向 QGraphicsScene 的指针)。不要在 itemChange() 中调用 setScene(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemCursorChange项目的光标将发生更改。值参数是新游标(即 QCursor)。不要在 itemChange() 中调用 setCursor(),因为此通知已传递。相反,您可以从 itemChange() 返回新的游标。
QGraphicsItem::ItemCursorHasChanged项目的光标已更改。值参数是新游标(即 QCursor)。不要调用 setCursor(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemToolTipChange项目的工具提示会更改。值参数是新的工具提示(即 QToolTip)。不要在 itemChange() 中调用 setToolTip(),因为此通知已传递。相反,您可以从 itemChange() 返回新的工具提示。
QGraphicsItem::ItemToolTipHasChanged项目的工具提示已更改。值参数是新的工具提示(即 QToolTip)。不要调用 setToolTip(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemFlagsChange项目的标志会更改。值参数是新标志(即 quint32)。不要在 itemChange() 中调用 setFlags(),因为此通知已传递。相反,您可以从 itemChange() 返回新标志。
QGraphicsItem::ItemFlagsHaveChanged项目的标志已更改。值参数是新标志(即 quint32)。不要在 itemChange() 中调用 setFlags(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemZValueChange项目的 Z 值将发生更改。值参数是新的 Z 值(即双精度值)。不要在 itemChange() 中调用 setZValue(),因为此通知已传递。相反,您可以从 itemChange() 返回新的 Z 值。
QGraphicsItem::ItemZValueHasChanged项目的 Z 值已更改。值参数是新的 Z 值(即双精度值)。不要在传递此通知时调用 setZValue()。返回值将被忽略。
QGraphicsItem::ItemOpacityChange项目的不透明度将发生更改。值参数是新的不透明度(即双精度)。不要在传递此通知时在 itemChange() 中调用 setOpacity()。相反,您可以从 itemChange() 返回新的不透明度。
QGraphicsItem::ItemOpacityHasChanged项目的不透明度已更改。值参数是新的不透明度(即双精度)。不要调用 setOpacity(),因为此通知已传递。返回值将被忽略。
QGraphicsItem::ItemScenePositionHasChanged项目的场景位置已更改。如果启用了 ItemSendsScenePositionChanges 标志,并且在项目的场景位置已更改(即,项目本身的位置或变换或任何祖先的位置或变换已更改)之后,将发送此通知。值参数是新的场景位置(与 scenePos() 相同),QGraphicsItem 忽略此通知的返回值(即只读通知)。

举例

以位置改变后发出通知举例,在构造函数通过setFlag(ItemSendsGeometryChanges);打开通知功能。

QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
switch (change) {
    case ItemPositionChange:
        qDebug()<<"位置将发生变化";
        break;

    case ItemPositionHasChanged:
        qDebug()<<"位置发生了变化";
        break;
    default:
        break;
    };
    return QGraphicsItem::itemChange(change, value);
}

演示效果如下:
请添加图片描述
当item状态发生改变时,会自动调用itemChange函数,利用switch case来判断item改变的通知类型,一种叫ItemPositionChange,一种叫ItemPositionHasChanged,通过Debug也能看出,一次移动会发出两次通知。从字面意思看,这两个通知一个叫【将要移动】,一个叫【已经移动】。
在这里插入图片描述
仔细阅读上述说明文档,能看出两者区别。

  • 接收到ItemPositionChange后,value这个值是新位置,通过调用pos可以获取原始位置,即未移动前的位置,而且会return新的位置。
  • 接收到ItemPositionHasChange后,value这个值也是新位置,但是调用pos获取的也是新位置,原始位置不能获取了,而且并不会return新的位置,只是个只读通知。
  • 5
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值