Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿
代码如下:
class ArrowItem : public QGraphicsItem
{
public:
    
const static float LINE_WIDTH;
    
const static float ARROW_SIZE;
public:
    ArrowItem(QGraphicsItem
* parent = 0);
    
~ArrowItem();
    
void setData(const QPointF& from,const QRectF& rect);
public:
    QRectF boundingRect()
const;
    
void paint(QPainter* painter,const QStyleOptionGraphicsItem* style,QWidget* widget);
private:
    QPointF computeTo(
const QPointF& from,const QRectF& to);
private:
    
bool mValid;
    QPointF mFrom;
    QPointF mTo;
    QPointF mP1;
    QPointF mP2;
    QRectF  mRect;
};

const float ArrowItem::LINE_WIDTH = 1.5f;
const float ArrowItem::ARROW_SIZE = 8.0f;

ArrowItem::ArrowItem(QGraphicsItem
* parent):
QGraphicsItem(parent),
mValid(
false)
{
}

ArrowItem::
~ArrowItem()
{
}

QPointF ArrowItem::computeTo(
const QPointF& from,const QRectF& to)
{
    QPointF center(to.center());
    QPointF top(center.x(),to.top());
    QPointF right(to.right(),center.y());
    QPointF bottom(center.x(),to.bottom());
    QPointF left(to.left(),center.y());

    
//left
    if(from.x() < to.left())
    {
        
if(from.y() < to.top())
        {
            QLineF line1(from,top);
            QLineF line2(from,left);
            
return line1.length() > line2.length() ? left : top;
        }
        
else if(from.y() > to.bottom())
        {
            QLineF line1(from,left);
            QLineF line2(from,bottom);
            
return line1.length() > line2.length() ? bottom : left;
        }
        
return left;
    }
    
//right
    if(from.x() > to.right())
    {
        
if(from.y() < to.top())
        {
            QLineF line1(from,top);
            QLineF line2(from,right);
            
return line1.length() > line2.length() ? right : top;
        }
        
else if(from.y() > to.bottom())
        {
            QLineF line1(from,bottom);
            QLineF line2(from,right);
            
return line1.length() > line2.length() ? right : bottom;
        }
        
return right;
    }

    
if(from.y() < to.top())
        
return top;
    
else if(from.y() > to.bottom())
        
return bottom;

    Q_ASSERT(
0);
    
return QPointF();
}

void ArrowItem::setData(const QPointF& from,const QRectF& rect)
{
    mValid 
= true;
    mFrom 
= from;
    mRect 
= rect;

    
if(rect.contains(from))
    {
        mValid 
= false;
        
return;
    }

    mTo 
= computeTo(mFrom,mRect);

    QLineF line(mFrom,mTo);
    qreal angle 
= ::acos(line.dx()/line.length());

    
if(line.dy() >= 0)
        angle 
= 3.14159*2 - angle;

    mP1 
= mTo + QPointF(sin(angle-PI/3)*ARROW_SIZE,cos(angle-PI/3)*ARROW_SIZE);
    mP2 
= mTo + QPointF(sin(angle-PI+PI/3)*ARROW_SIZE,cos(angle-PI+PI/3)*ARROW_SIZE);
}

QRectF ArrowItem::boundingRect()
const
{
    qreal extra 
= (LINE_WIDTH + ARROW_SIZE)/2.0;
    QRectF rect
= QRectF(mFrom,QSizeF(mTo.x()-mFrom.x(),mTo.y()-mFrom.y())).normalized().
        adjusted(
-extra,-extra,extra,extra);
    
return rect;
}

void ArrowItem::paint(QPainter* painter,const QStyleOptionGraphicsItem* style,QWidget* widget)
{
    
if(!mValid)
        
return;
    painter
->setRenderHint(QPainter::Antialiasing);
    QPen p(QColor::fromRgb(
79,136,187));
    painter
->setBrush(QBrush(p.color()));
    p.setWidthF(LINE_WIDTH);
    painter
->setPen(p);
    painter
->drawLine(mFrom,mTo);
    painter
->drawPolygon(QPolygonF()<<mTo<<mP1<<mP2);
}

void ArrowItem::setData(const QPointF& from,const QRectF& rect)
该函数第一个参数为箭头起点,rect为箭头指向的矩形框,该函数会自动计算箭头终点和箭头相关参数
该代码经过测试 - 完全可以使用
参考:
http://www.cnblogs.com/liulun/p/3833006.html
posted on 2015-12-15 13:10 ccsdu2009 阅读(4978) 评论(0)  编辑 收藏 引用 所属分类: QT编程

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理