我有一个class Edge : public QGraphicsItem
,它实现了从一个节点到另一个节点的绘制箭头(下面的屏幕)。
现在我需要添加在自己身上绘制箭头(弧线)的功能。
我无法绘制弧线,覆盖boundingRect()
和shape()
。
下面的代码是我画箭头或弧线的地方。完整项目在这里 -> github。
Edge::Edge(Node *sourceNode, Node *destNode)
: id(_idStatic++), arrowSize(15)
{
setFlag(QGraphicsItem::ItemIsSelectable);
source = sourceNode;
dest = destNode;
source->addEdge(this);
if(source != dest)
dest->addEdge(this);
adjust();
}
QPolygonF Edge::nPolygonMath() const {
QPolygonF nPolygon;
if (source != dest) {
QLineF line = QLineF(sourcePoint.x(), sourcePoint.y(), destPoint.x(), destPoint.y());
qreal radAngle = line.angle() * M_PI / 180;
qreal selectionOffset = 3;
qreal dx = selectionOffset * sin(radAngle);
qreal dy = selectionOffset * cos(radAngle);
QPointF offset1 = QPointF(dx, dy);
QPointF offset2 = QPointF(-dx, -dy);
nPolygon << line.p1() + offset1
<< line.p1() + offset2
<< line.p2() + offset2
<< line.p2() + offset1;
} else {
nPolygon << mapFromItem(source, -Node::Radius, -Node::Radius)
<< mapFromItem(source, Node::Radius, -Node::Radius)
<< mapFromItem(source, Node::Radius, Node::Radius)
<< mapFromItem(source, -Node::Radius, Node::Radius);
}
return nPolygon;
}
QRectF Edge::boundingRect() const
{
if (!source || !dest)
return QRectF();
return nPolygonMath().boundingRect();
}
QPainterPath Edge::shape() const{
QPainterPath ret;
ret.addPolygon(nPolygonMath());
return ret;
}
void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
if (!source || !dest)
return;
painter->setPen(QPen((option->state & QStyle::State_Selected ? Qt::cyan: Qt::black), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
if (source != dest) {
QLineF line(sourcePoint, destPoint);
if (qFuzzyCompare(line.length(), qreal(0.)))
return;
// Draw the line itself
painter->drawLine(line);
// Draw the arrows
double angle = std::atan2(-line.dy(), line.dx());
QPointF destArrowP1 = destPoint + QPointF(sin(angle - M_PI / 1.8) * qMin(arrowSize, line.length()),
cos(angle - M_PI / 1.8) * qMin(arrowSize, line.length()));
QPointF destArrowP2 = destPoint + QPointF(sin(angle - M_PI + M_PI / 1.8) * qMin(arrowSize, line.length()),
cos(angle - M_PI + M_PI / 1.8) * qMin(arrowSize, line.length()));
painter->setBrush((option->state & QStyle::State_Selected ? Qt::cyan: Qt::black));
painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);
} else {
painter->drawArc(mapFromItem(source, Node::Radius, 0).x(),
mapFromItem(source, Node::Radius, 0).y(),
2 * Node::Radius, 2 * Node::Radius, 16 * -90, 16 * 180);
}
}