Qt World Summit: Register Today!


How to draw triangle points in QtChart?



  • Hello everyone,

    I want to draw some points with triangle symbol, but the marker shape only support circle and rectangle shape.
    I can create a triangle shape as QImage and send it to the QBrush of QScatterSeries, but if I want to draw I border, I still can only draw a circular or rectangular border.
    Is there anyway I can draw a triangle point with triangle border?
    0_1510718066716_pic.png


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    If your QImage based triangle does the job, then why not update that QImage with a new triangle with the border painted ? It's essentially a question of setting a pen and a brush to your requested colours.

    Hope it helps



  • @SGaist Hi SGaist, Thank you for your answering.
    Maybe I didn't make it clear, I want to draw some triangles with border, and others without border, so I have to use setBorderColor or set Pen of QScatterSeries to add the border in some cases.



  • @SGaist I rewrited the source code of QtChart and now it works! Thank you all the same!


  • Lifetime Qt Champion

    What did you modify ?



  • @NeeMoo ,

    void Widget::paintEvent(QPaintEvent *event){
    QPainter painter(this);
    QPen pen;
    pen.setWidth(4);
    pen.setColor(Qt::red);
    painter.setBrush(Qt::blue);
    painter.setPen(pen);
    QPointF *points = new QPointF[3];
    points[0] = QPointF(100,50);
    points[1] = QPointF(50,150);
    points[2] = QPointF(150,150);
    painter.drawPolygon(points,3);
    }



  • @SGaist I rewrited the ScatterChartItem and ScatterSeries, added a TriangleMarker:
    void ScatterChartItem::createPoints(int count)
    {
    for (int i = 0; i < count; ++i) {

        QGraphicsItem *item = 0;
    
        switch (m_shape) {
        case QScatterSeries::MarkerShapeCircle: {
            item = new CircleMarker(0, 0, m_size, m_size, this);
            const QRectF &rect = item->boundingRect();
            item->setPos(-rect.width() / 2, -rect.height() / 2);
            break;
        }
        case QScatterSeries::MarkerShapeRectangle:
            item = new RectangleMarker(0, 0, m_size, m_size, this);
            item->setPos(-m_size / 2, -m_size / 2);
            break;
    	case QScatterSeries::MarkerShapeTriangle:
    		item = new TriangleMarker(0, 0, m_size, m_size, this);
    		item->setPos(-m_size / 2, -m_size / 2);
        default:
            qWarning() << "Unsupported marker type";
            break;
        }
        m_items.addToGroup(item);
    }
    

    }

    class TriangleMarker : public QGraphicsPolygonItem
    {

    public:
    TriangleMarker(qreal x, qreal y, qreal w, qreal h, ScatterChartItem *parent)
    : QGraphicsPolygonItem(QPolygonF() << QPointF(x, y + h) << QPointF(x + w, y + h) << QPointF(x + w / 2.0f, y), parent),
    m_parent(parent)
    {
    setAcceptHoverEvents(true);
    setFlag(QGraphicsItem::ItemIsSelectable);
    }

    protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
    QGraphicsPolygonItem::mousePressEvent(event);
    m_parent->markerPressed(this);
    m_parent->setMousePressed();
    }
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
    {
    QGraphicsPolygonItem::hoverEnterEvent(event);
    m_parent->markerHovered(this, true);
    }
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
    {
    QGraphicsPolygonItem::hoverLeaveEvent(event);
    m_parent->markerHovered(this, false);
    }
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    {
    QGraphicsPolygonItem::mouseReleaseEvent(event);
    m_parent->markerReleased(this);
    if (m_parent->mousePressed())
    m_parent->markerSelected(this);
    m_parent->setMousePressed(false);
    }
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
    {
    QGraphicsPolygonItem::mouseDoubleClickEvent(event);
    m_parent->markerDoubleClicked(this);
    }

    private:
    ScatterChartItem *m_parent;
    };

    But the legend of that maker shape is not correct, so it should have a little work on legend.


  • Lifetime Qt Champion

    Nice !

    Did you consider contributing your changes ?



  • Yeah of course! But I don't know how to contribute my code, I'm a beginner of programming, haha, could you give me some advice?


  • Lifetime Qt Champion

    Sure, the starting point is here. Take your time to go through it. The first time setup might take some time but following the documentation it's not that complicated.



  • @NeeMoo Nice! I'm also a beginner right now, so could you explain where exactly the data-point is in relation to the triangle? If I'm interpreting your code right, I think it's in the bottom left corner?
    Because I would like to have two kinds of TriangleMarker, one pointing up with the data-point at the top corner and one pointing down with the data-point at the bottom corner. To do that I would just have to make two TriangleMarker classes and change the 3 QPoints that make up the QPolygonF, right?


Log in to reply