[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.

    !http://i41.tinypic.com/67uy9s.jpg(Nodes)!

    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)
    {
    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?



  • 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.