Qt通过重写QGraphicItem实现绘制、拖动、缩放、旋转矩形

更新时间:2023-05-14 13:20:18 阅读: 评论:0

Qt通过重写QGraphicItem实现绘制、拖动、缩放、旋转矩形
Qt 通过重写QGraphicItem实现绘制、拖动、缩放、旋转矩形
本例程通过重写了⼀个类,继承⾃QGraphicItem,来实现了在qgraphicsScene上绘制、拖动、缩放、旋转矩形。
效果如下:
其实要实现绘制、拖动、缩放矩形都不难,难的是在旋转之后还要⽀持缩放。
我的思路是:
1.实现绘制矩形:只要定义⼀个全局变量QRectF m_oldRect,在外⾯矩形⼤⼩传进来,然后在paint函数⾥⾯绘制这个矩形就⾏
2.实现拖动矩形:重写mouPressEvent,mouMoveEvent,mouReleaEvent,记录⿏标按下的起始点和移动时候的点,并⽤moveBy()函数来移动矩形即可
3.实现缩放:在矩形内部靠近4条边的地⽅定义4个矩形,当⿏标按下的时候在这4个矩形⽅框内,则将矩形往4个⽅向拉伸
4.实现旋转:
我给之前定义的矩形全部配⼀个QPolygonF,因为我只能通过绘制多边形的⽅式来画出旋转之后的矩形。
矩形正上⽅的圆圈我是通过三⾓函数+直线⽅程来计算,让其始终绘制在矩形左右两个顶点的中垂线上⽅。
当⿏标落在圆形内部的时候可以控制矩形旋转。
在矩形旋转之后,再进⾏拉伸的时候,我是通过的计算⿏标的点离对⾯的边的距离来重新计算矩形的⼤⼩,然后计算对应的QPolygonF的⼤⼩。
主要代码如下:
mygraphicrectitem.h
#ifndef MYGRAPHICRECTITEM_H
#define MYGRAPHICRECTITEM_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
enum STATE_FLAG{
DEFAULT_FLAG=0,
MOV_LEFT_LINE,//标记当前为⽤户按下矩形的左边界区域
MOV_TOP_LINE,//标记当前为⽤户按下矩形的上边界区域
MOV_RIGHT_LINE,//标记当前为⽤户按下矩形的右边界区域
MOV_BOTTOM_LINE,//标记当前为⽤户按下矩形的下边界区域
MOV_RIGHTBOTTOM_RECT,//标记当前为⽤户按下矩形的右下⾓
MOV_RECT,//标记当前为⿏标拖动图⽚移动状态
ROTATE//标记当前为旋转状态
};
欧洲杯冠军2016class myGraphicRectItem:public QObject,public QGraphicsItem
{
Q_OBJECT
public:
myGraphicRectItem(QGraphicsItem *parent = nullptr);
//myGraphicRectItem(QRectF m_OriginRect = QRectF(0,0,100,100));严格英文
QRectF boundingRect() const;meid
~
myGraphicRectItem();
void tRectSize(QRectF mrect,bool bRetRotateCenter = true);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void mouPressEvent(QGraphicsSceneMouEvent *event);
void mouMoveEvent(QGraphicsSceneMouEvent *event);
void mouReleaEvent(QGraphicsSceneMouEvent *event);
void SetRotate(qreal RotateAngle,QPointF ptCenter=QPointF(-999,-999));
QPointF getRotatePoint(QPointF ptCenter, QPointF ptIn, qreal angle);//获取旋转后的点
QList getRotatePoints(QPointF ptCenter,QList ptIns,qreal angle);//获取多个旋转后的点
QPolygonF getRotatePolygonFromRect(QPointF ptCenter,QRectF rectIn,qreal angle);//将矩形旋转之后返回多边形QRectF getCrtPosRectToSceen();
QRectF m_SmallRotateRect;//矩形顶部⽤来表⽰旋转的标记的矩形
QPolygonF m_SmallRotatePolygon;//矩形顶部⽤来表⽰旋转的标记的矩形旋转后形成的多边形
QPointF getSmallRotateRectCenter(QPointF ptA,QPointF ptB);//获取旋转时候矩形正上⽅的旋转标记矩形
QRectF getSmallRotateRect(QPointF ptA,QPointF ptB);
bool m_bRotate;
qreal m_RotateAngle;
QPointF m_RotateCenter;
private:
QRectF m_oldRect;
QPolygonF m_oldRectPolygon;
QRectF m_RotateAreaRect;
bool m_bResize;
QPolygonF m_insicedPolygon;
QRectF m_insicedRectf;
QPolygonF m_leftPolygon;
QRectF m_leftRectf;
QPolygonF m_topPolygon;
QRectF m_topRectf;
QPolygonF m_rightPolygon;
QRectF m_rightRectf;
QPolygonF m_bottomPolygon;
QRectF m_bottomRectf;
// QPolygonF m_rbPolygon;
/
/ QRectF m_rbRectf;
QPointF m_startPos;
STATE_FLAG m_StateFlag;
QPointF *pPointFofSmallRotateRect;
protected:
};
#endif // MYGRAPHICRECTITEM_H
mygraphicrectitem.cpp
#include “mygraphicrectitem.h”
#include
#include
qcc是什么
myGraphicRectItem::myGraphicRectItem(QGraphicsItem *parent):
m_bResize(fal),
m_oldRect(0,0,100,100),
m_bRotate(fal),
m_RotateAngle(0),
m_StateFlag(DEFAULT_FLAG)
{
//tParent(parent);
tRectSize(m_oldRect);
tToolTip(“Click and drag me!”); //提⽰
tCursor(Qt::ArrowCursor); //改变光标形状,⼿的形状
tFlag(QGraphicsItem::ItemIsMovable);
// tAcceptDrops(true);
pPointFofSmallRotateRect = new QPointF[4];
SetRotate(0);
tFlag(QGraphicsItem::ItemIsSelectable);//
}
QRectF myGraphicRectItem::boundingRect() const
{
//return m_oldRectPolygon.boundingRect();
QRectF boundingRectF = m_oldRectPolygon.boundingRect();
return QRectF(boundingRectF.x()-40,boundingRectF.y()-40,boundingRectF.width()+80,boundingRect
F.height()+80); }
myGraphicRectItem::~myGraphicRectItem()
{
delete []pPointFofSmallRotateRect;
pPointFofSmallRotateRect = nullptr;
}
void myGraphicRectItem::tRectSize(QRectF mrect, bool bRetRotateCenter)
{
m_oldRect = mrect;
if(bRetRotateCenter)
我在学外语{
m_RotateCenter.tX(m_oldRect.x()+m_oldRect.width()/2);
m_RotateCenter.tY(m_oldRect.y()+m_oldRect.height()/2);
}
m_oldRectPolygon = getRotatePolygonFromRect(m_RotateCenter,m_oldRect,m_RotateAngle);
m_insicedRectf = QRectF(m_oldRect.x()+8,m_oldRect.y()+8,m_oldRect.width()-16,m_oldRect.height()-16);
m_insicedPolygon =getRotatePolygonFromRect(m_RotateCenter,m_insicedRectf,m_RotateAngle);
m_leftRectf = QRectF(m_oldRect.x(),m_oldRect.y(),8,m_oldRect.height()-8);
m_leftPolygon = getRotatePolygonFromRect(m_RotateCenter,m_leftRectf,m_RotateAngle);pupil的音标
m_topRectf = QRectF(m_oldRect.x()+8,m_oldRect.y(),m_oldRect.width()-8,8);
m_topPolygon = getRotatePolygonFromRect(m_RotateCenter,m_topRectf,m_RotateAngle);
m_rightRectf = QRectF(m_oldRect.right()-8,m_oldRect.y()+8,8,m_oldRect.height()-16);
m_rightPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rightRectf,m_RotateAngle);
m_bottomRectf = QRectF(m_oldRect.x(),m_oldRect.bottom()-8,m_oldRect.width()-8,8);
m_bottomPolygon = getRotatePolygonFromRect(m_RotateCenter,m_bottomRectf,m_RotateAngle);
// m_rbRectf = QRectF(m_oldRect.right()-8,m_oldRect.bottom()-8,8,8);
// m_rbPolygon = getRotatePolygonFromRect(m_RotateCenter,m_rbRectf,m_RotateAngle);叉子的英文
m_SmallRotateRect = pLeft(),pRight());//矩形正上⽅的旋转标记矩形
m_SmallRotatePolygon = getRotatePolygonFromRect(m_RotateCenter,m_SmallRotateRect,m_RotateAngle);
}
void myGraphicRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
QPen mPen = QPen(Qt::yellow);
建造师培训
painter->tPen(mPen);
//绘制旋转后的矩形
painter->drawPolygon(m_oldRectPolygon);
//绘制旋转圆形
mPen.tWidth(2);
mPen.tColor(Qt::green);
painter->tPen(mPen);
QPointF pf = getSmallRotateRectCenter(m_oldRectPolygon[0],m_oldRectPolygon[1]);
QRectF rect = QRectF(pf.x()-10,pf.y()-10,20,20);
painter->drawEllip(rect);//绘制圆形
painter->drawPoint(pf);//绘制点
}
void myGraphicRectItem::mouPressEvent(QGraphicsSceneMouEvent *event)
{
if(event->button()== Qt::LeftButton)
{
m_startPos = event->pos();//⿏标左击时,获取当前⿏标在图⽚中的坐标,
if(ainsPoint(m_startPos,Qt::WindingFill))//旋转矩形
{
tCursor(Qt::PointingHandCursor);
m_StateFlag = ROTATE;
}
el if(ainsPoint(m_startPos,Qt::WindingFill))//在矩形内框区域时按下⿏标,则可拖动图⽚
{bictor
tCursor(Qt::ClodHandCursor); //改变光标形状,⼿的形状
m_StateFlag = MOV_RECT;//标记当前为⿏标拖动图⽚移动状态
}
el if(ainsPoint(m_startPos,Qt::WindingFill))
{
tCursor(Qt::SizeHorCursor);
m_StateFlag = MOV_LEFT_LINE;//标记当前为⽤户按下矩形的左边界区域
}
el if(ainsPoint(m_startPos,Qt::WindingFill))
{
tCursor(Qt::SizeHorCursor);
m_StateFlag = MOV_RIGHT_LINE;//标记当前为⽤户按下矩形的右边界区域
六级准考证号查询}
el if(ainsPoint(m_startPos,Qt::WindingFill))
{
tCursor(Qt::SizeVerCursor);
m_StateFlag = MOV_TOP_LINE;//标记当前为⽤户按下矩形的上边界区域
}
el if(ainsPoint(m_startPos,Qt::WindingFill))
{
tCursor(Qt::SizeVerCursor);
m_StateFlag = MOV_BOTTOM_LINE;//标记当前为⽤户按下矩形的下边界区域
}
// el if(ainsPoint(m_startPos,Qt::WindingFill))
// {
// tCursor(Qt::SizeFDiagCursor);
// m_StateFlag = MOV_RIGHTBOTTOM_RECT;//标记当前为⽤户按下矩形的右下⾓
// }
el
{
m_StateFlag = DEFAULT_FLAG;
}
}
el
{
QGraphicsItem::mouPressEvent(event);
}
}
void myGraphicRectItem::mouMoveEvent(QGraphicsSceneMouEvent event)
{
if(m_StateFlag == ROTATE)
{
int nRotateAngle = atan2((event->pos().x()-m_RotateCenter.x()),(event->pos().y()-m_RotateCenter.y()))180/M_PI;

本文发布于:2023-05-14 13:20:18,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/108167.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:矩形   旋转   绘制   拖动   区域   缩放   实现
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图