Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Trouble creating an arrow between two QGraphicsItems
Forum Updated to NodeBB v4.3 + New Features

[Solved] Trouble creating an arrow between two QGraphicsItems

Scheduled Pinned Locked Moved General and Desktop
5 Posts 2 Posters 6.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Guigui
    wrote on last edited by
    #1

    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?

    1 Reply Last reply
    0
    • podsvirovP Offline
      podsvirovP Offline
      podsvirov
      wrote on last edited by
      #2

      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?

      1 Reply Last reply
      0
      • G Offline
        G Offline
        Guigui
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          Guigui
          wrote on last edited by
          #4

          _<

          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.

          1 Reply Last reply
          0
          • podsvirovP Offline
            podsvirovP Offline
            podsvirov
            wrote on last edited by
            #5

            Always happy to help!

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved