强制 QGraphicsItem 使用 z 值并忽略父子关系

Arw*_*wen 5 c++ qt qgraphicsview qgraphicsitem qgraphicsscene

我在使用QGraphicsItem类时遇到问题。

有一个 base_parent、base_part、part_1、part_2。base_parent 是 base_part 的父级。part_1 和 part_2 是 base_part 的子代。我想要做的是以part_1和part_2堆叠在base_parent后面和base_part堆叠在base_parent前面的方式设置这些项目的Z值。所以我实现的是这样的:

  base_part->setParentItem(base_parent);
  part_1->setParentItem(base_part);
  part_2->setParentItem(base_part);
Run Code Online (Sandbox Code Playgroud)

起初尝试使用 setZValue() 设置 z 值,但显然它不起作用。

base_parent->setZValue(0);
base_part->setZValue(1);
part_1->setZValue(-1);
part_2->setZValue(-2);
Run Code Online (Sandbox Code Playgroud)

文档中说:

项目的子项堆叠在父项的顶部

我放弃了,但后来我看到了另一个参数。

您可以在项目上调用 setZValue() 以将其显式堆叠在其他同级项目的顶部或下方。项目的默认 Z 值为 0。具有相同 Z 值的项目按插入顺序堆叠。

您可以调用 stackBefore() 对子项列表重新排序。这将直接修改插入顺序。

您可以设置 ItemStacksBehindParent 标志以将子项堆叠在其父项后面。

所以我尝试设置ItemStacksBehindParent标志,但它移动了整个孩子后面的堆叠,这意味着 base_part、part_1 和 part_2 被堆叠在 base_parent 后面。

后来我发现了另一个标志,ItemNegativeZStacksBehindParent.

如果 z 值为负,该项目会自动堆叠在其父项后面。此标志使 setZValue() 能够切换 ItemStacksBehindParent。这个标志是在 Qt 4.6 中引入的。

所以我又试了一次:

  base_part->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
  part_1->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
  part_2->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
Run Code Online (Sandbox Code Playgroud)

使用此标志将 part_1 和 part_2 堆叠在 base_part 后面,但它们仍然堆叠在 base_parent 前面。

我想知道是否有办法强制项目仅使用 Z 值并忽略父子关系。

坚持层次结构的主要原因是我想为base_part做动画,part_1和part_2必须沿着base_part移动,当然我知道解决这个问题的方法,如果我把part_1和part_2的parent设置为base_parent,我将能够得到我想要的结果,但是我还必须为 part_1 和 part_2 设置动画,这有点令人讨厌。

jwe*_*rek 0

我认为目前在 Qt 中没有办法使QGraphicsItem对象的 z 顺序完全独立于父/子关系,如果您需要在这种程度上控制 z 顺序,您最好的选择是将所有内容置于顶层并进行管理父母和孩子自己通过QGraphicsItem::setTransform(...)

基本上,内置父/子实现所做的主要事情,除了跟踪项目树之外,它还将转换从父级树向下传播到子级,但是您可以通过矩阵算术自己完成此操作,就像QTransform这样引擎盖下的 3x3 矩阵。