0

で有限オートマトンを表示したいQGraphicsView。サブクラス化 QGraphicsItem状態を表すクラスがあります。これは、状態間の移動を指定するインスタンスへのNodeポインターを保持します。各リンクには、その起点と宛先 (インスタンスLinkへのポインター) も保持されます。Node

リンクの状態の 1 つを移動することによって、コードでリンクを更新 (再描画) したいと考えています。リンクを呼び出す方法paint()や、リンクを強制的に更新する方法が見つかりません。

ノードの実装:

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::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());
}
4

1 に答える 1

0

リンクはノードを接続しているように見えるため、ユーザーがアイテムを移動しているときに ItemPositionChange が呼び出されるため、ItemPositionHasChanged ではなく ItemPositionChange を使用する必要があります。

次に、リンクがノードに接続されたままになるようにリンクの位置を更新し、その update() を呼び出す必要があります。

したがって、問題は ItemPositionHasChanged が ItemPositionChange である必要があり、ノードが変更されたときではなく、リンクが変更されたときにノードを更新する必要があることです。

于 2013-01-30T13:24:24.730 に答える