zoukankan      html  css  js  c++  java
  • Qt 通过重写QGraphicItem实现绘制、拖动、旋转、缩放椭圆

    本例程通过重写了一个类,继承自QGraphicItem,来实现了在qgraphicsScene上绘制、拖动、旋转、缩放椭圆
    效果如下:
    在这里插入图片描述

    核心代码如下:
    mygraphicrectitem.h

     1 #ifndef MYGRAPHICRECTITEM_H
     2 #define MYGRAPHICRECTITEM_H
     3 #include <QObject>
     4 #include <QWidget>
     5 #include <QMouseEvent>
     6 #include <QGraphicsScene>
     7 #include <QGraphicsRectItem>
     8 #include <QGraphicsSceneMouseEvent>
     9 #include <QRect>
    10 #include <QPainter>
    11 #include <QPolygon>
    12 #include <QList>
    13 #include <QTransform>
    14 enum STATE_FLAG{
    15     DEFAULT_FLAG=0,
    16     MOV_LEFT_LINE,//标记当前为用户按下矩形的左边界区域
    17     MOV_TOP_LINE,//标记当前为用户按下矩形的上边界区域
    18     MOV_RIGHT_LINE,//标记当前为用户按下矩形的右边界区域
    19     MOV_BOTTOM_LINE,//标记当前为用户按下矩形的下边界区域
    20     MOV_RIGHTBOTTOM_RECT,//标记当前为用户按下矩形的右下角
    21     MOV_RECT,//标记当前为鼠标拖动图片移动状态
    22     ROTATE//标记当前为旋转状态
    23 };
    24 enum SHAPE_TYPE{
    25     RECTANGLE=0,
    26     CIRCLE
    27 };
    28 
    29 class myGraphicRectItem:public QObject,public QGraphicsItem
    30 {
    31     Q_OBJECT
    32 public:
    33     SHAPE_TYPE m_ShapeType;
    34     myGraphicRectItem(QGraphicsItem *parent = nullptr);
    35     //myGraphicRectItem(QRectF m_OriginRect = QRectF(0,0,100,100));
    36     QRectF  boundingRect() const;
    37     QPainterPath shape() const;
    38     QPainterPath getCollideShape();
    39     ~myGraphicRectItem();
    40     void setRectSize(QRectF mrect,bool bResetRotateCenter = true);
    41     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    42     void mousePressEvent(QGraphicsSceneMouseEvent *event);
    43     void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    44     void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    45     void SetRotate(qreal RotateAngle);
    46     QPointF getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle);//获取旋转后的点
    47     QList<QPointF> getRotatePoints(QPointF ptCenter,QList<QPointF> ptIns,qreal angle);//获取多个旋转后的点
    48     QPolygonF getRotatePolygonFromRect(QPointF ptCenter,QRectF rectIn,qreal angle);//将矩形旋转之后返回多边形
    49     QRectF getCrtPosRectToSceen();
    50     QPolygonF getCrtPolygonToScreen();
    51 
    52     QPointF getSmallRotateRectCenter(QPointF ptA,QPointF ptB);//获取旋转时候矩形正上方的旋转标记矩形
    53     QRectF  getSmallRotateRect(QPointF ptA,QPointF ptB);
    54     bool    m_bRotate;
    55     qreal   m_RotateAngle;
    56     QPointF m_RotateCenter;
    57 
    58 private:
    59     QRectF  m_oldRect;
    60     QPolygonF m_oldRectPolygon;
    61     QRectF  m_RotateAreaRect;
    62     bool    m_bResize;
    63     QPolygonF m_insicedPolygon;
    64     QRectF  m_insicedRectf;
    65     QPolygonF m_leftPolygon;
    66     QRectF  m_leftRectf;
    67     QPolygonF m_topPolygon;
    68     QRectF  m_topRectf;
    69     QPolygonF m_rightPolygon;
    70     QRectF  m_rightRectf;
    71     QPolygonF m_bottomPolygon;
    72     QRectF  m_bottomRectf;
    73     QRectF m_SmallRotateRect;//矩形顶部用来表示旋转的标记的矩形
    74     QPolygonF m_SmallRotatePolygon;//矩形顶部用来表示旋转的标记的矩形旋转后形成的多边形
    75 //    QPolygonF m_rbPolygon;
    76 //    QRectF  m_rbRectf;
    77     QPointF m_startPos;
    78     STATE_FLAG m_StateFlag;
    79     QPointF *pPointFofSmallRotateRect;
    80 protected:
    81 
    82 };
    83 
    84 #endif // MYGRAPHICRECTITEM_H

    mygraphicrectitem.cpp

      1 #include "mygraphicrectitem.h"
      2 #include <QtMath>
      3 #include <QDebug>
      4 
      5 myGraphicRectItem::myGraphicRectItem(QGraphicsItem *parent):
      6     m_ShapeType(RECTANGLE),
      7     m_bResize(false),
      8     m_oldRect(0,0,100,100),
      9     m_bRotate(false),
     10     m_RotateAngle(0),
     11     m_StateFlag(DEFAULT_FLAG)
     12 {
     13     //setParent(parent);
     14     setRectSize(m_oldRect);
     15     setToolTip("Click and drag me!");  //提示
     16     setCursor(Qt::ArrowCursor);   //改变光标形状,手的形状
     17     setFlag(QGraphicsItem::ItemIsMovable);
     18     pPointFofSmallRotateRect = new QPointF[4];
     19     SetRotate(0);
     20     //setFlag(QGraphicsItem::ItemIsSelectable);//
     21     setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
     22 }
     23 
     24 QRectF myGraphicRectItem::boundingRect() const//用来控制本item绘制区域
     25 {
     26     QPainterPath path;
     27     path.addPolygon(m_oldRectPolygon);
     28     path.addPolygon(m_SmallRotatePolygon);
     29     return path.boundingRect();
     30 }
     31 
     32 QPainterPath myGraphicRectItem::shape() const//用来控制检测碰撞collide和鼠标点击hit响应区域
     33 {
     34     QPainterPath path;
     35     path.addPolygon(m_oldRectPolygon);
     36     path.addPolygon(m_SmallRotatePolygon);
     37     return path;
     38 }
     39 
     40 QPainterPath myGraphicRectItem::getCollideShape()
     41 {
     42     QPainterPath path;
     43     if(m_ShapeType==RECTANGLE)
     44     {
     45         path.addPolygon(m_oldRectPolygon);
     46     }
     47     else if(m_ShapeType == CIRCLE)
     48     {
     49         QPainterPath pathTemp;
     50         pathTemp.addEllipse(m_oldRect);
     51         QTransform trans;
     52         trans.translate(m_RotateCenter.x(),m_RotateCenter.y());
     53         trans.rotate(m_RotateAngle);//QTransform是绕(0,0)点旋转的,所以转之前要先平移到圆心,然后旋转,然后再平移回来
     54         trans.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
     55         path = trans.map(pathTemp);
     56     }
     57     return path;
     58 }
     59 
     60 myGraphicRectItem::~myGraphicRectItem()
     61 {
     62     delete []pPointFofSmallRotateRect;
     63     pPointFofSmallRotateRect = nullptr;
     64 }
     65 
     66 void myGraphicRectItem::setRectSize(QRectF mrect, bool bResetRotateCenter)
     67 {
     68     m_oldRect = mrect;
     69     if(bResetRotateCenter)
     70     {
     71         m_RotateCenter.setX(m_oldRect.x()+m_oldRect.width()/2);
     72         m_RotateCenter.setY(m_oldRect.y()+m_oldRect.height()/2);
     73     }
     74     m_oldRectPolygon = getRotatePolygonFromRect(m_RotateCenter,m_oldRect,m_RotateAngle);
     75 
     76     m_insicedRectf = QRectF(m_oldRect.x()+8,m_oldRect.y()+8,m_oldRect.width()-16,m_oldRect.height()-16);
     77     m_insicedPolygon =getRotatePolygonFromRect(m_RotateCenter,m_insicedRectf,m_RotateAngle);
     78 
     79     m_leftRectf = QRectF(m_oldRect.x(),m_oldRect.y(),8,m_oldRect.height()-8);
     80     m_leftPolygon = getRotatePolygonFromRect(m_RotateCenter,m_leftRectf,m_RotateAngle);
     81 
     82     m_topRectf = QRectF(m_oldRect.x()+8,m_oldRect.y(),m_oldRect.width()-8,8);
     83     m_topPolygon = getRotatePolygonFromRect(m_RotateCenter,m_topRectf,m_RotateAngle);
     84 
     85     m_rightRectf = QRectF(m_oldRect.right()-8,m_oldRect.y()+8,8,m_oldRect.height()-16);
     86     m_rightPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rightRectf,m_RotateAngle);
     87 
     88     m_bottomRectf = QRectF(m_oldRect.x(),m_oldRect.bottom()-8,m_oldRect.width()-8,8);
     89     m_bottomPolygon = getRotatePolygonFromRect(m_RotateCenter,m_bottomRectf,m_RotateAngle);
     90 
     91     m_SmallRotateRect = getSmallRotateRect(mrect.topLeft(),mrect.topRight());//矩形正上方的旋转标记矩形
     92     m_SmallRotatePolygon = getRotatePolygonFromRect(m_RotateCenter,m_SmallRotateRect,m_RotateAngle);
     93 
     94 }
     95 
     96 void myGraphicRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
     97 {
     98     QPen mPen;
     99 //    if(this->isSelected())
    100 //    {
    101 //        mPen= QPen(Qt::lightGray);
    102 //    }
    103 //    else
    104 //    {
    105         mPen= QPen(Qt::yellow);
    106 //    }
    107     painter->setPen(mPen);
    108     if(m_ShapeType == RECTANGLE)
    109     {
    110         //绘制旋转后的矩形
    111         painter->drawPolygon(m_oldRectPolygon);
    112         //绘制旋转圆形
    113         mPen.setWidth(2);
    114         mPen.setColor(Qt::green);
    115         painter->setPen(mPen);
    116         QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
    117         QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
    118         painter->drawEllipse(rect);//绘制圆形
    119         painter->drawPoint(pf);//绘制点
    120         //有重叠的情况
    121         if(!this->scene()->collidingItems(this).isEmpty())
    122         {
    123            QPainterPath path,pathOthers;
    124            QList<QGraphicsItem *> lstcolliItems = this->scene()->collidingItems(this);
    125            int nColliNum = lstcolliItems.count();
    126            for(int i = 0;i<nColliNum;i++)
    127            {
    128                myGraphicRectItem* pTempItem = (myGraphicRectItem*)this->scene()->collidingItems(this)[i];
    129                if(pTempItem->zValue()==0)
    130                {
    131                    QPainterPath tempPath = pTempItem->getCollideShape();
    132                    tempPath.translate(pTempItem->pos());//转换到view中的坐标
    133                    pathOthers += tempPath;//记录与本item重叠的item的路径
    134                }
    135            }
    136            path.addPolygon(m_oldRectPolygon);
    137            path.translate(this->pos());//转换到view中的坐标
    138            path &= pathOthers;//计算重叠部分的路径path
    139            path.translate(-this->pos().x(),-this->pos().y());//转换回本Item中的坐标
    140            QBrush brush(Qt::cyan);
    141            mPen.setColor(Qt::blue);
    142            painter->setPen(mPen);
    143            painter->setBrush(brush);
    144            painter->drawPath(path);//绘制重叠区域
    145         }
    146     }
    147     else if(m_ShapeType == CIRCLE)
    148     {
    149 //        //绘制旋转后的矩形
    150 //        painter->drawRect(m_oldRect);
    151 //        painter->drawPolygon(m_oldRectPolygon);
    152         //绘制旋转后的圆形
    153         QTransform trans0;
    154         QPainterPath path0;
    155         trans0.translate(m_RotateCenter.x(),m_RotateCenter.y());
    156         trans0.rotate(m_RotateAngle,Qt::ZAxis);
    157         trans0.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
    158         path0.addEllipse(m_oldRect);
    159         path0 = trans0.map(path0);//将pathTemp旋转m_RotateAngle角度
    160         painter->drawPath(path0);//drawPolygon(m_oldRectPolygon);
    161         //绘制旋转圆形标记
    162         mPen.setWidth(2);
    163         mPen.setColor(Qt::green);
    164         painter->setPen(mPen);
    165         QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
    166         QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
    167         painter->drawEllipse(rect);//绘制圆形
    168         painter->drawPoint(pf);//绘制点
    169         //有重叠的情况
    170         if(!this->scene()->collidingItems(this).isEmpty())
    171         {
    172            QPainterPath path,pathOthers;
    173            QList<QGraphicsItem *> lstcolliItems = this->scene()->collidingItems(this);
    174            int nColliNum = lstcolliItems.count();
    175            for(int i = 0;i<nColliNum;i++)
    176            {
    177                myGraphicRectItem* pTempItem = (myGraphicRectItem*)this->scene()->collidingItems(this)[i];
    178                if(pTempItem->zValue()==0)
    179                {
    180                    QPainterPath tempPath = pTempItem->getCollideShape();
    181                    tempPath.translate(pTempItem->pos());//转换到view中的坐标
    182                    pathOthers += tempPath;//记录与本item重叠的item的路径
    183                }
    184            }
    185            QTransform trans;
    186            //旋转的时候,QTransform是绕坐标轴的(0,0)点旋转的,所以先要平移到坐标轴0,0点,然后的旋转,然后移回到原来的位置
    187            trans.translate(m_RotateCenter.x(),m_RotateCenter.y());
    188            trans.rotate(m_RotateAngle);
    189            trans.translate(-m_RotateCenter.x(),-m_RotateCenter.y());
    190            path.addEllipse(m_oldRect);
    191            path = trans.map(path);//将pathTemp旋转m_RotateAngle角度
    192            path.translate(this->pos());//转换到view中的坐标
    193            path &= pathOthers;//计算重叠部分的路径path
    194            path.translate(-this->pos().x(),-this->pos().y());//转换回本Item中的坐标
    195            QBrush brush(Qt::cyan);
    196            mPen.setColor(Qt::blue);
    197            painter->setPen(mPen);
    198            painter->setBrush(brush);
    199            painter->drawPath(path);//绘制重叠区域
    200         }
    201     }
    202 //scene()->update();
    203 }
    204 
    205 void myGraphicRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
    206 {
    207     if(event->button()== Qt::LeftButton)
    208     {
    209         //setSelected(true);
    210         m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
    211         if(m_SmallRotatePolygon.containsPoint(m_startPos,Qt::WindingFill))//旋转矩形
    212         {
    213             setCursor(Qt::PointingHandCursor);
    214             m_StateFlag = ROTATE;
    215         }
    216         else if(m_insicedPolygon.containsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下鼠标,则可拖动图片
    217         {
    218             setCursor(Qt::ClosedHandCursor);   //改变光标形状,手的形状
    219             m_StateFlag = MOV_RECT;//标记当前为鼠标拖动图片移动状态
    220         }
    221         else if(m_leftPolygon.containsPoint(m_startPos,Qt::WindingFill))
    222         {
    223             setCursor(Qt::SizeHorCursor);
    224             m_StateFlag = MOV_LEFT_LINE;//标记当前为用户按下矩形的左边界区域
    225         }
    226         else if(m_rightPolygon.containsPoint(m_startPos,Qt::WindingFill))
    227         {
    228             setCursor(Qt::SizeHorCursor);
    229             m_StateFlag = MOV_RIGHT_LINE;//标记当前为用户按下矩形的右边界区域
    230         }
    231         else if(m_topPolygon.containsPoint(m_startPos,Qt::WindingFill))
    232         {
    233             setCursor(Qt::SizeVerCursor);
    234             m_StateFlag = MOV_TOP_LINE;//标记当前为用户按下矩形的上边界区域
    235         }
    236         else if(m_bottomPolygon.containsPoint(m_startPos,Qt::WindingFill))
    237         {
    238             setCursor(Qt::SizeVerCursor);
    239             m_StateFlag = MOV_BOTTOM_LINE;//标记当前为用户按下矩形的下边界区域
    240         }
    241 //        else if(m_rbPolygon.containsPoint(m_startPos,Qt::WindingFill))
    242 //        {
    243 //            setCursor(Qt::SizeFDiagCursor);
    244 //            m_StateFlag = MOV_RIGHTBOTTOM_RECT;//标记当前为用户按下矩形的右下角
    245 //        }
    246         else
    247         {
    248             m_StateFlag = DEFAULT_FLAG;
    249         }
    250     }
    251     else
    252     {
    253         QGraphicsItem::mousePressEvent(event);
    254     }
    255 }
    256 
    257 void myGraphicRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    258 {
    259     if(m_StateFlag == ROTATE)
    260     {
    261        int nRotateAngle = atan2((event->pos().x()-m_RotateCenter.x()),(event->pos().y()-m_RotateCenter.y()))*180/M_PI;
    262        SetRotate(180-nRotateAngle);       
    263        //qDebug()<<nRotateAngle;
    264     }
    265     else if(m_StateFlag == MOV_RECT)
    266     {
    267         QPointF point = (event->pos() - m_startPos);
    268         moveBy(point.x(), point.y());
    269         setRectSize(m_oldRect);
    270         scene()->update();
    271     }
    272     else if(m_StateFlag == MOV_LEFT_LINE)
    273     {
    274         QPointF pf = QPointF((m_oldRectPolygon.at(1).x()+m_oldRectPolygon.at(2).x())/2,((m_oldRectPolygon.at(1).y()+m_oldRectPolygon.at(2).y())/2));
    275         //计算到右侧边中点的距离
    276         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    277         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    278         qreal dis2RT = sqrt((event->pos().x()-m_oldRectPolygon.at(1).x())*(event->pos().x()-m_oldRectPolygon.at(1).x()) +(event->pos().y()-m_oldRectPolygon.at(1).y())*(event->pos().y()-m_oldRectPolygon.at(1).y()));
    279         if(dis<16||dis2LT>dis2RT)
    280         {
    281             return;
    282         }
    283         else
    284         {
    285             QRectF newRect(m_oldRect);
    286             newRect.setLeft(m_oldRect.right()-dis);
    287             newRect.setRight(m_oldRect.right());
    288             setRectSize(newRect,false);
    289             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    290             m_oldRect.moveCenter(m_RotateCenter);
    291             setRectSize(m_oldRect);
    292             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    293         }
    294     }
    295     else if(m_StateFlag == MOV_TOP_LINE)
    296     {
    297         //底边中点
    298         QPointF pf = QPointF((m_oldRectPolygon.at(2).x()+m_oldRectPolygon.at(3).x())/2,((m_oldRectPolygon.at(2).y()+m_oldRectPolygon.at(3).y())/2));
    299         //计算到底边中点的距离
    300         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    301         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    302         qreal dis2LB = sqrt((event->pos().x()-m_oldRectPolygon.at(3).x())*(event->pos().x()-m_oldRectPolygon.at(3).x()) +(event->pos().y()-m_oldRectPolygon.at(3).y())*(event->pos().y()-m_oldRectPolygon.at(3).y()));
    303         if(dis<16||dis2LT>dis2LB)
    304         {
    305             return;
    306         }
    307         else
    308         {
    309             QRectF newRect(m_oldRect);
    310             newRect.setTop(m_oldRect.bottom()-dis);
    311             newRect.setBottom(m_oldRect.bottom());
    312             setRectSize(newRect,false);
    313             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    314             m_oldRect.moveCenter(m_RotateCenter);
    315             setRectSize(m_oldRect);
    316             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    317         }
    318     }
    319     else if(m_StateFlag == MOV_RIGHT_LINE)
    320     {
    321         QPointF pf = QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(3).x())/2,((m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(3).y())/2));
    322         //计算到左侧边中点的距离
    323         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    324         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    325         qreal dis2RT = sqrt((event->pos().x()-m_oldRectPolygon.at(1).x())*(event->pos().x()-m_oldRectPolygon.at(1).x()) +(event->pos().y()-m_oldRectPolygon.at(1).y())*(event->pos().y()-m_oldRectPolygon.at(1).y()));
    326         if(dis<16||dis2LT<dis2RT)
    327         {
    328             return;
    329         }
    330         else
    331         {
    332             QRectF newRect(m_oldRect);
    333             newRect.setLeft(m_oldRect.left());
    334             newRect.setRight(m_oldRect.left()+dis);
    335             setRectSize(newRect,false);
    336             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    337             m_oldRect.moveCenter(m_RotateCenter);
    338             setRectSize(m_oldRect);
    339             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    340         }
    341     }
    342     else if(m_StateFlag == MOV_BOTTOM_LINE)
    343     {
    344         //顶边中点
    345         QPointF pf = QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(1).x())/2,((m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(1).y())/2));
    346         //计算到底边中点的距离
    347         qreal dis = sqrt((event->pos().x()-pf.x())*(event->pos().x()-pf.x()) +(event->pos().y()-pf.y())*(event->pos().y()-pf.y()));
    348         qreal dis2LT = sqrt((event->pos().x()-m_oldRectPolygon.at(0).x())*(event->pos().x()-m_oldRectPolygon.at(0).x()) +(event->pos().y()-m_oldRectPolygon.at(0).y())*(event->pos().y()-m_oldRectPolygon.at(0).y()));
    349         qreal dis2LB = sqrt((event->pos().x()-m_oldRectPolygon.at(3).x())*(event->pos().x()-m_oldRectPolygon.at(3).x()) +(event->pos().y()-m_oldRectPolygon.at(3).y())*(event->pos().y()-m_oldRectPolygon.at(3).y()));
    350         if(dis<16||dis2LT<dis2LB)
    351         {
    352             return;
    353         }
    354         else
    355         {
    356             QRectF newRect(m_oldRect);
    357             newRect.setTop(m_oldRect.top());
    358             newRect.setBottom(m_oldRect.top()+dis);
    359             setRectSize(newRect,false);
    360             m_RotateCenter=QPointF((m_oldRectPolygon.at(0).x()+m_oldRectPolygon.at(2).x())/2,(m_oldRectPolygon.at(0).y()+m_oldRectPolygon.at(2).y())/2);
    361             m_oldRect.moveCenter(m_RotateCenter);
    362             setRectSize(m_oldRect);
    363             scene()->update();//必须要用scene()->update(),不能用update();否则会出现重影
    364         }
    365     }
    366 }
    367 
    368 void myGraphicRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    369 {
    370     setCursor(Qt::ArrowCursor);
    371     if(m_StateFlag == MOV_RECT)
    372     {
    373         m_StateFlag = DEFAULT_FLAG;
    374     }
    375     else {
    376         QGraphicsItem::mouseReleaseEvent(event);
    377     }
    378 }
    379 
    380 void myGraphicRectItem::SetRotate(qreal RotateAngle)
    381 {
    382     m_bRotate = true;
    383     m_RotateAngle = RotateAngle;
    384     setRectSize(m_oldRect);
    385     if(this->scene()!=nullptr)
    386         this->scene()->update();
    387 }
    388 
    389 QPointF myGraphicRectItem::getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle)
    390 {
    391     double dx = ptCenter.x();
    392     double dy = ptCenter.y();
    393     double x = ptIn.x();
    394     double y = ptIn.y();
    395     double xx,yy;
    396     xx = (x-dx)*cos(angle*M_PI/180)-(y-dy)*sin(angle*M_PI/180)+dx;
    397     yy = (x-dx)*sin(angle*M_PI/180)+(y-dy)*cos(angle*M_PI/180)+dy;
    398 
    399     return QPointF(xx,yy);
    400 }
    401 
    402 QList<QPointF> myGraphicRectItem::getRotatePoints(QPointF ptCenter, QList<QPointF> ptIns, qreal angle)
    403 {
    404     QList<QPointF> lstPt;
    405     for(int i = 0;i<ptIns.count();i++)
    406     {
    407         lstPt.append(getRotatePoint(ptCenter,ptIns.at(i),angle));
    408     }
    409     return lstPt;
    410 }
    411 
    412 QPolygonF myGraphicRectItem::getRotatePolygonFromRect(QPointF ptCenter, QRectF rectIn, qreal angle)
    413 {
    414     QVector<QPointF> vpt;
    415     QPointF pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
    416     vpt.append(pf);
    417     pf = getRotatePoint(ptCenter,rectIn.topRight(),angle);
    418     vpt.append(pf);
    419     pf = getRotatePoint(ptCenter,rectIn.bottomRight(),angle);
    420     vpt.append(pf);
    421     pf = getRotatePoint(ptCenter,rectIn.bottomLeft(),angle);
    422     vpt.append(pf);
    423     pf = getRotatePoint(ptCenter,rectIn.topLeft(),angle);
    424     vpt.append(pf);
    425     return QPolygonF(vpt);
    426 }
    427 
    428 QRectF myGraphicRectItem::getCrtPosRectToSceen()
    429 {
    430     QRectF retRect = QRectF(m_oldRect.x()+pos().x(),m_oldRect.y()+pos().y(),m_oldRect.width(),m_oldRect.height());
    431     return retRect;
    432 }
    433 
    434 QPolygonF myGraphicRectItem::getCrtPolygonToScreen()
    435 {
    436     QVector<QPointF> vpt;
    437     for(int i = 0;i<m_oldRectPolygon.length();i++)
    438     {
    439         vpt.append(QPointF(m_oldRectPolygon[i].x()+pos().x(),m_oldRectPolygon[i].y()+pos().y()));
    440     }
    441     return QPolygonF(vpt);
    442 }
    443 QRectF myGraphicRectItem::getSmallRotateRect(QPointF ptA,QPointF ptB)
    444 {
    445     QPointF pt = getSmallRotateRectCenter(ptA,ptB);
    446     return QRectF(pt.x()-10,pt.y()-10,20,20);
    447 }
    448 QPointF myGraphicRectItem::getSmallRotateRectCenter(QPointF ptA,QPointF ptB)
    449 {
    450     QPointF ptCenter = QPointF((ptA.x()+ptB.x())/2,(ptA.y()+ptB.y())/2);//A,B点的中点C
    451     //中垂线方程式为 y=x*k + b;
    452     qreal x,y;//旋转图标矩形的中心
    453     if(abs(ptB.y()-ptA.y())<0.1)
    454     {
    455         if(ptA.x()<ptB.x())//矩形左上角在上方
    456         {
    457             x = ptCenter.x();
    458             y = ptCenter.y()-20;
    459         }
    460         else//矩形左上角在下方
    461         {
    462             x = ptCenter.x();
    463             y = ptCenter.y()+20;
    464         }
    465     }
    466     else if(ptB.y()>ptA.y())//顺时针旋转0-180
    467     {
    468         qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
    469         qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
    470         //求AB线中垂线上离AB中点20个像素的点C的坐标
    471         x = 20*cos(atan(k))+ptCenter.x();
    472         y = k*x+b;
    473     }
    474     else if(ptB.y()<ptA.y())//顺时针旋转180-360
    475     {
    476         qreal k = (ptA.x()-ptB.x())/(ptB.y()-ptA.y());//中垂线斜率
    477         qreal b = (ptA.y()+ptB.y())/2-k*(ptA.x()+ptB.x())/2;
    478         //求AB线中垂线上离AB中点20个像素的点C的坐标
    479         x = -20*cos(atan(k))+ptCenter.x();
    480         y = k*x+b;
    481     }
    482     return QPointF(x,y);
    483 }
  • 相关阅读:
    Vue3.0 是如何变得更快的?
    阿里云 Centos7 安装mongodb
    ASP.Net Core5.0 EF Core使用记录
    MongoDB批量更新|按条件更新SQL|批量删除某个字段
    Layui单元格编辑获取修改前的值
    判断字符串出现的多个位置
    原生JavaScript的DOM操作汇总
    @Value值为null、#和$的区别
    Dubbo推荐用法
    Dubbo 服务化最佳实践
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13862407.html
Copyright © 2011-2022 走看看