1
votes

I'm working on a graphical shape editor that uses the QGraphicsScene/QGraphicsView as its basis. I have a lot of experience with the scene/view framework and understand it fairly well. The issue that I'm having is that QGraphicsScene::items always returns items in the insertion order (either ascending or descending) regardless of the Z-order or the use of QGraphicsItem::stackBefore call.

The issue is that, as with most graphics editors, I need to be able to move shapes forward or backward in the stacking order. At the end, to save the resulting data, I have to traverse the list of the items in the scene and save each item's data in whatever format I'm using.

The only way that I've found to do this is that I have to remove items from the scene and reinsert them in the desired stacking order. In this particular task, it's a small number of items and happens without noticeable delay, but in a related editor, it could be many thousands.

While the QGraphicsItem::zValue and QGraphicsItem::stackBefore allow me to influence the drawing order, neither of them changes the order that gets returned from QGraphicsScene::items. Since the data I ultimately save needs to reflect the drawing order, I have to remove and reinsert to get the correct ordering at the end.

Questions:

  • Have I've overlooked any other techniques for managing items within the scene that will influence the results of QGraphicsItem::items?
  • Or is there another method for traversing the items within the scene that will give me the drawing order?
1
Isn't that what QGraphicsScene::items() does?Kevin Krammer
No, as I said, QGraphicsScene::items always returns in insertion order. Changes made by QGraphicsItem::stackBefore and QGraphicsItem::setZValue don't affect the of QGraphicsScene::items.goug
Interesting, the documentation said it would do that.Kevin Krammer
It says "stacking order" but that's not what I'm getting back after using stackBefore to change the stacking order. I put in some debug code to dump the item list both before and after, and the list in the same order in both cases. And unfortunately, because of the task, I MUST have the list in the correct stacking order. The only way I've found to do that is to remove the items and re-insert them in the desired order.goug
As of Qt5.12 at least, I disagree and find that QGraphicsItem::stackBefore() does alter the order returned from QGraphicsScene::items(), just as the documentation states it does. doc.qt.io/qt-5/qgraphicsitem.html#sorting "You can call stackBefore() to reorder the list of children. This will directly modify the insertion order."JonBrave

1 Answers

2
votes

I can confirm that QGraphicsScene::items() and items(sortOrder) return the item list in the original creation and stacking order, which does not at all agree with the docs.

However, I found that by using

QGraphicsScene::items( QGraphicsScene::itemsBoundingRect, Qt::IntersectsItemBoundingRect, sortOrder) I do get the items in the correct drawing order, so this function apparently takes calls to QGraphicsItem::stackBefore() into account.

i don't use the z-order feature so I can't comment on whether that works in this scenario or not.