[Solved] Trouble creating an arrow between two QGraphicsItems

  • I am trying to implement some kind of node graph GUI. I started the work based on the "Diagram Scene":http://qt-project.org/doc/qt-5.0/qtwidgets/graphicsview-diagramscene.html and the "Elastic Node":http://qt-project.org/doc/qt-5.0/qtwidgets/graphicsview-elasticnodes.html 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.

    !http://i43.tinypic.com/339mums.jpg(Nodes and arrow)!

    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)

    painter->setRenderHint(QPainter::HighQualityAntialiasing, true);

    // Don't paint the arrow if both connectors are superposed
    if (m_sourceConnector->collidesWithItem(m_destConnector))


    // 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)
    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 << line().p1() << arrowP1 << arrowP2;


    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));
        linkLine.translate(2 * d * std::sin((a - 180) / 180 * PI), 2*d*std::cos((a - 180) / 180 * PI));


    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?

  • From documentation:

    Items live in their own local coordinate system.

    • QGraphicsItem::pos() - Returns the position of the item in parent coordinates.
    • QGraphicsItem::scenePos() - Returns the item's position in scene coordinates.

    Items NodeLinkItem, m_sourceConnector, m_destConnector have the same parent?

  • I was just about to try reparenting the objects:

    • I don't set any parent for NodeLinkItem.
    • m_sourceConnector and m_destConnector are of type NodeConnectorItem.
    • NodeConnectorItem are instanciated when NodeItem objects are created, and I set the new node as parent for every of it's Connectors.

    So I suppose since the connector has a NodeItem as parent, connectors return coordinates relative to this node. I'll try setting no parents to the connectors.

  • _<

    For unknown reasons, the connectors are not painted if I don't set their parent node. However, using scenePos() instead of pos() fixed everything. Thank you for your answer.

  • Always happy to help!

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.