PDA

View Full Version : Child GraphicsItems Not Getting itemChange()



jawbreak
19th October 2010, 23:28
I have two QGraphicsRectItem objects with one being the child of the other. So I have a parent and a child.

I'm trying to track the movement of the child whenever the parent is moved.

These two flags are set for both object.
setFlag(ItemIsMovable);
setFlag(ItemSendsGeometryChanges);

When the parent item is moved itemChanged() is called with ItemPositionHasChanged,
but the child's is never called. I tried using ItemParentHasChanged, but that isn't being called.

Anyone have any thoughts? Here's the function:



QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
switch (change) {
case ItemPositionHasChanged:
qDebug() << "ItemPositionHasChanged";
break;

case ItemParentHasChanged:
qDebug() << "ItemParentHasChanged;
break;
default:
break;
};

return QGraphicsItem::itemChange(change, value);
}

wysota
20th October 2010, 01:20
The child's method will only be called when it moves relative to the parent. ItemParentHasChanged would be called if you set a different parent for an item. The only thing that possibly changes in the situation you describe is the scene position but there is no itemChange() version of that (and good, it would be terribly slow).

jawbreak
20th October 2010, 02:26
The child's method will only be called when it moves relative to the parent. ItemParentHasChanged would be called if you set a different parent for an item. The only thing that possibly changes in the situation you describe is the scene position but there is no itemChange() version of that (and good, it would be terribly slow).

Yeah, I see that itemChange() is only called when a particular item is moved and not when it's parent is moved as well.

I totally misread ItemParentHasChanged, you are right, it's about an item's parent changing and I misread it as the parent position changing. duh! heh

While typing this response I figured out how to do what I was trying to do.

Basically I was trying to do something like the elastic nodes example with arrows connecting nodes, but instead have arrows connecting child nodes. So what I needed was a way to update the arrows when the parent nodes moved.

I solved this by doing the following:



QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
QList<QGraphicsItem*> children;
switch (change) {
case ItemPositionHasChanged:
children = this->childItems();
foreach(QGraphicsItem* child, children) {
static_cast<Node*>(child)->updateEdges();
}
this->updateEdges();
break;
default:
break;
};

return QGraphicsItem::itemChange(change, value);
}

void Node::updateEdges() {
foreach(Arrow* arrow, m_arrows)
arrow->adjust();
}


So what happens is when the parent's itemChange() is called, it gets a list of it's children and tells them to update their arrows.

Thanks for the reply it got me thinking and back on track to solving this.