本例程通过重写了一个类,继承自QGraphicItem,来实现了在qgraphicsScene上绘制、拖动、旋转、缩放椭圆
效果如下:
核心代码如下:
mygraphicrectitem.h
CSDN QT大纲:Qt开发必备技术栈学习路线和资料
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 }
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓