Qt繪製自定義箭頭圖元

weixin_40395778發表於2019-05-05
#ifndef LINK_H
#define LINK_H

#include <QGraphicsItem>

class Link : public QObject,public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)
public:
    explicit Link(QObject *parent = 0);

    virtual QRectF boundingRect() const;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    void setLineItem(QPointF startP, QPointF endP);
    void setColor(QColor color);

private:
    void CreatePointNodes(void);

private:
    QPointF         m_EndP;//這個點是直線的終點
    QPointF         m_points[3];//箭頭端的三個端點
    QColor          m_Color;

};

#endif // LINK_H
#include "link.h"
#include "math.h"
#include <QPainter>


Link::Link(QObject *parent) : QObject(parent)
{
    //setFlag(ItemIsMovable);
    setFlag(ItemIsSelectable);
    setAcceptHoverEvents(true);

    m_Color = Qt::green;
}

QRectF Link::boundingRect() const
{
    return QRectF(0, 0, m_EndP.x(), m_EndP.y());
}

void Link::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setRenderHint(QPainter::Antialiasing, true);                   //設定反走樣,防鋸齒
    QPen pen(m_Color, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
    QBrush brush(m_Color, Qt::SolidPattern);

    painter->setPen(pen);
    painter->setBrush(brush);

    QLineF line(0, 0, m_EndP.x(), m_EndP.y());
    painter->drawLine(line);

    painter->drawPolygon(m_points, 3);

  /*  pen.setWidth(1);
    painter->setPen(pen);
    brush.setColor(QColor(0,0,0,0));
    painter->setBrush(brush);
    painter->drawRect(boundingRect());
  */
}

void Link::setLineItem(QPointF startP, QPointF endP)
{
    m_EndP = endP - startP;

    CreatePointNodes();
}

void Link::setColor(QColor color)
{
    m_Color = color;
}

void Link::CreatePointNodes(void)
{  
    //箭頭直線與水平方向的夾角再加pi
    float angle = atan2(m_EndP.y(), m_EndP.x()) + 3.1415926; 
    //這兩個值需要根據實際場景的座標大小進行調整,
    float ExtRefArrowLenght = 20;//箭頭末端大小的長度,
    float ExtRefArrowDegrees = 0.3;//箭頭末端頂角的一半

    m_points[0] = m_EndP;
     //求得箭頭點1座標
    m_points[1].setX(m_EndP.x() + ExtRefArrowLenght * cos(angle - ExtRefArrowDegrees));
    m_points[1].setY(m_EndP.y() + ExtRefArrowLenght * sin(angle - ExtRefArrowDegrees));
    //求得箭頭點2座標
    m_points[2].setX(m_EndP.x() + ExtRefArrowLenght * cos(angle + ExtRefArrowDegrees));
    m_points[2].setY(m_EndP.y() + ExtRefArrowLenght * sin(angle + ExtRefArrowDegrees));
}

呼叫方式如下,需要在標頭檔案中宣告一個link指標,如果需要圖元根據端點座標的變化實時更新位置,可以通過設定link
(圖元名字)的setLineItem()函式和setPos()函式。

    //通過這個呼叫,新增圖元
    link = new Link(this);
    link->setLineItem(startP, endP);
    link->setPos(startP);
    this->_scene->addItem(link);

轉載自:https://blog.csdn.net/u012061464/article/details/80571328

相關文章