Qt绘制自定义箭头图元

#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

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值