0

I want to show a finite automata in a QGraphicsView. Subclassing QGraphicsItem I have a class representing state: Node which holds pointers to Link instances which specify moves between states. Each link also holds its origin and destination (pointers to Node instances).

I want my code to update (redraw) a link by moving one of its states. I can'thet find a way to call paint() or somehow force the links to update.

Node implementation:

Node::Node( QGraphicsItem * parent) :
    QGraphicsObject(parent)
{
    setFlag(ItemIsMovable);
    setFlag(ItemSendsGeometryChanges);
    setCacheMode(DeviceCoordinateCache);
    setZValue(-1);
}

void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen(Qt::black);
    if(option->state & QStyle::State_Selected)
    {
        pen.setStyle(Qt::DotLine);
        pen.setWidth(2);
    }
    painter->setPen(pen);
    painter->drawEllipse(-m_size.width()/2,-m_size.height()/2,m_size.width(),m_size.height());
    painter->drawText(boundingRect(),Qt::AlignCenter,m_label);
}

QRectF Node::boundingRect() const
{
    return QRectF(topLeft(),m_size);
}
//...

void Node::addLink(Link* newLink)
{
    links.append(newLink);
}

// protected members
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch (change)
    {
    case ItemPositionHasChanged:
        foreach (Link *link, links)
        {
            link->update(); // This has no effect
        }
        break;
    default:
        break;
    };
    return QGraphicsItem::itemChange(change, value);
}

Link implementation:

Link::Link(QGraphicsItem *parent) :
    QGraphicsObject(parent)
{
    setFlag(ItemIsMovable);
    setFlag(ItemSendsGeometryChanges);
    setCacheMode(DeviceCoordinateCache);
    setZValue(-1);
}

Link::Link(Node *From, Node *To, QGraphicsItem *parent ):
    QGraphicsObject(parent),
    from(From),
    to(To)
{
    setFlag(ItemIsMovable);
    setFlag(ItemSendsGeometryChanges);
    setCacheMode(DeviceCoordinateCache);
    setZValue(-1);
}

void Link::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    m_painter = painter;
    QPen pen(Qt::black);
    if(option->state & QStyle::State_Selected)
    {
        pen.setStyle(Qt::DotLine);
        pen.setWidth(2);
    }
    painter->setPen(pen);
    painter->drawLine(from->pos(),to->pos());
}

QRectF Link::boundingRect() const
{
    return QRectF(from->pos(),to->pos());
}
sorush-r
  • 10,490
  • 17
  • 89
  • 173

1 Answers1

0

Since your link appears to be connecting nodes you need to use ItemPositionChange rather than ItemPositionHasChanged because ItemPositionChange will be called as the user is moving the item.

Then you should update the position of your link so that it is still connected to your node and call its update().

So your problems are ItemPositionHasChanged should be ItemPositionChange, and also you want to updated the node when the link changes, not when the node changes from what I can tell.

paulm
  • 5,629
  • 7
  • 47
  • 70