QGraphicsView
に有限オートマトンを表示したい。サブクラスQGraphicsItem
私は状態を表すクラスを持っています:Node
は、状態間の移動を指定するLink
インスタンスへのポインタを保持します。各リンクは、起点と宛先も保持します(Node
インスタンスへのポインタ)。他のオブジェクトを移動して特定のQGraphicsObjectを更新する
私のコードでは、状態の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());
}