I am trying to implement some kind of node graph GUI. I started the work based on the Diagram Scene [qt-project.org] and the Elastic Node [qt-project.org] examples. I have some difficulties however in customizing the nodes and draw arrows between them.
So far, I subclassed the QGraphicsProxyWidget class to create some kind of dialog looking node. The node is further customized by adding labels and connectors, which are subclasses of QGraphicsPathItem.
The problem is that the arrow never appear. I managed however to make it work between the connectors alone.
Here’s my code to draw the arrow (almost the same as the Diagram Scene example).
void NodeLinkItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->setRenderHint(QPainter::HighQualityAntialiasing, true);
painter->setPen(pen());
painter->setBrush(Qt::white);
// Don't paint the arrow if both connectors are superposed
if (m_sourceConnector->collidesWithItem(m_destConnector))
return;
// Draw the line part of the arrow
QLineF centerLine(m_sourceConnector->pos(), m_destConnector->pos());
QPolygonF endPolygon = m_destConnector->path().toFillPolygon();
QPointF p1 = endPolygon.first() + m_destConnector->pos();
QPointF p2;
QPointF intersectPoint;
QLineF polyLine;
for (int i = 1; i < endPolygon.count(); ++i) {
p2 = endPolygon.at(i) + m_destConnector->pos();
polyLine = QLineF(p1, p2);
QLineF::IntersectType intersectType = polyLine.intersect(centerLine, &intersectPoint);
if (intersectType == QLineF::BoundedIntersection)
break;
p1 = p2;
}
setLine(QLineF(intersectPoint, m_sourceConnector->pos()));
// Draw the arrowhead part of the arrow
double angle = std::acos(line().dx() / line().length());
if (line().dy() >= 0)
angle = (PI * 2) - angle;
qreal arrowSize = 10;
QPointF arrowP1 = line().p1() + QPointF(std::sin(angle + PI / 3) * arrowSize,
std::cos(angle + PI / 3) * arrowSize);
QPointF arrowP2 = line().p1() + QPointF(std::sin(angle + PI - PI / 3) * arrowSize,
std::cos(angle + PI - PI / 3) * arrowSize);
m_arrowhead.clear();
m_arrowhead << line().p1() << arrowP1 << arrowP2;
painter->drawLine(line());
painter->drawPolygon(m_arrowhead);
if (isSelected()) {
painter->setPen(QPen(Qt::black, 1, Qt::DashLine));
QLineF linkLine = line();
double a = linkLine.angle();
double d = 4;
linkLine.translate(d * std::sin(a / 180 * PI), d * std::cos(a / 180 * PI));
painter->drawLine(linkLine);
linkLine.translate(2 * d * std::sin((a - 180) / 180 * PI), 2*d*std::cos((a - 180) / 180 * PI));
painter->drawLine(linkLine);
}
}
Any idea why it wouldn’t work when the connector is inside another node? Is it possible that the coordinates returned around lines 15-17 are in parent coordinates, aka. coordinates inside the node?
↧