Parent–child relationship between items
Imagine that you need to create a graphics item that contains multiple geometric primitives, for example, a circle inside a rectangle. You can create both items and add them to the scene individually, but this solution is inconvenient. First, when you need to remove that combination from the scene, you would need to manually delete both items. However, more importantly, when you need to move or transform the combination, you will need to calculate positions and complex transformations for each graphics item.
Fortunately, graphics items do not have to be a flat list of items added directly into the scene. Items can be added into any other items, forming a parent–child relationship very similar to the relationship of QObject that we observed in the last chapter:
Adding an item as a child of another item has the following consequences:
- When the parent item is added to the scene, the child item automatically becomes part of that scene, so there is no need to call QGraphicsScene::addItem() for it.
- When the parent item is deleted, its children are also deleted.
- When the parent item is hidden using the hide() or setVisible(false) functions, the child items will also be hidden.
- Most importantly, the child's coordinate system is derived from the parent's coordinate system instead of the scene's. This means that when the parent is moved or transformed, all children are also affected. The child's position and transformations are relative to the parent's coordinate system.
For a better understanding of pos() and the involved coordinate systems, think of post-it notes again. If you put a note on a larger sheet of paper and then had to determine its exact position, how would you do it? Probably like this: "The note's upper-left corner is positioned 3 cm to the right and 5 cm to the bottom from the paper's top-left edge". In the Graphics View world, this will correspond to a parentless item whose pos() function returns a position in the scene coordinates, since the item's origin is directly pinned to the scene. On the other hand, say you put a note A on top of a (larger) note B, which is already pinned on a paper, and you have to determine A's position; how would you describe it this time? Probably by saying that note A is placed on top of note B or "2 cm to the right and 1 cm to the bottom from the top-left edge of note B". You most likely wouldn't use the underlying paper as a reference since it is not the next point of reference. This is because if you move note B, A's position regarding the paper will change, whereas A's relative position to B still remains unchanged. To switch back to Graphics View, the equivalent situation is an item that has a parent item. In this case, the pos() function's returned value is expressed in the coordinate system of its parent. So, setPos() and pos() specify the position of the item's origin in relation to the next (higher) point of reference. This can be the scene or the item's parent item.
Keep in mind, however, that changing an item's position does not affect the item's internal coordinate system.