Forcing QGraphicsItem to use z value and ignore the parent child relationship
Asked Answered
T

1

8

I have problem using QGraphicsItem class.

There is a base_parent, base_part, part_1, part_2. The base_parent is the parent of the base_part. part_1 and part_2 are children of the base_part. What I want to do is to set the Z value of this items in a way that part_1 and part_2 stack behind the base_parent and the base_part stacks in front of the base_parent. So what I've implemented is something like this:

  base_part->setParentItem(base_parent);
  part_1->setParentItem(base_part);
  part_2->setParentItem(base_part);

At first the tried setting the z value using setZValue() but obviously it didn't work.

base_parent->setZValue(0);
base_part->setZValue(1);
part_1->setZValue(-1);
part_2->setZValue(-2);

In the documentation it is said that:

An item's children are stacked on top of the parent

I was giving up but then I saw another parameter.

You can call setZValue() on an item to explicitly stack it on top of, or under, other sibling items. The default Z value for an item is 0. Items with the same Z value are stacked by insertion order.

You can call stackBefore() to reorder the list of children. This will directly modify the insertion order.

You can set the ItemStacksBehindParent flag to stack a child item behind its parent.

So I tried setting the ItemStacksBehindParent flag but it moved the stacked the whole child behind, meaning the base_part, part_1 and part_2 were stacked behind the base_parent.

Afterwards I found another flag, ItemNegativeZStacksBehindParent.

The item automatically stacks behind it's parent if it's z-value is negative. This flag enables setZValue() to toggle ItemStacksBehindParent. This flag was introduced in Qt 4.6.

So I tried again:

  base_part->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
  part_1->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);
  part_2->setFlag(QGraphicsItem::ItemNegativeZStacksBehindParent);

Using this flag stacks part_1 and part_2 behind the base_part but they are still stack in front of the base_parent.

I want to know if there's a way to force items to use only Z value and ignore the parent child relationship.

The main reason for insisting on hierarchical structure is that I want to animate the base_part and the part_1 and part_2 must move along the base_part, Of course I know my way around this problem, If only I set parent of the part_1 and part_2 to base_parent, I'll be able to get the result I wanted, but then I have to animate part_1 and part_2 as well which is a little nasty.

Tabbi answered 28/7, 2016 at 11:35 Comment(0)
T
0

I think that currently in Qt there is no way to make the z-order of QGraphicsItem objects be totally independent of parent/child relationships, and if you need control of the z-order to this degree your best option is to make everything toplevel and manage parents and child yourself via QGraphicsItem::setTransform(...)

Basically the main thing that the built-in parent/child implementation is doing, beyond just keeping track of the tree of items, it propagating transformations down the tree from parents to children, but you can do this yourself via matrix arithmetic, as QTransform is just a 3x3 matrix under the hood.

Thicket answered 11/5, 2023 at 23:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.