赞
踩
各个控件的对象名设置如下,其中graphicsView是Graphics View控件,提升为自定义的MGraphicsView类,关于控件提升请参照我的另一篇博客:
VS+Qt应用开发-控件提升-以Label为例
首先贴上完整代码:
#pragma once /****************** 类功能:锚点类,主要功能如下: 1.绘制锚点; 2.接收锚点的鼠标事件,从而对图形进行拖动或改变形状 作者:zh 修改时间:2021-12-24 *******************/ #include <QObject> #include <QAbstractGraphicsShapeItem> #include <QPainter> #include "globalVar.h" class CMyAdjustPoint : public QObject, public QAbstractGraphicsShapeItem { Q_OBJECT public: enum POINT_TYPE //锚点的类型,根据图形的类型而异 { Center = 0, //图形中心,所有的图形 EdgeStart, EdgeEnd, EdgeLU, EdgeRU, EdgeL, EdgeR, EdgeLD, EdgeRD, Rotate }; //非Center的锚点是矩形的,指定phi值可让矩形锚点进行选择 CMyAdjustPoint(QAbstractGraphicsShapeItem *parent, QPointF p,double phi, POINT_TYPE type); ~CMyAdjustPoint(); //获取/设置锚点位置 QPointF getPoint() { return m_point; } void setPoint(QPointF p) { m_point = p; } //设置锚点的角度 void setPhi(double phi); protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); //重绘事件 void mouseMoveEvent(QGraphicsSceneMouseEvent *event); //鼠标移动事件,用于常规拖动和修改形状 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); //鼠标双击事件,用于多边形的增点和减点 private: QPointF m_point; //锚点在父对象的坐标位置,即在图像中的坐标 POINT_TYPE m_type; //锚点的类型 double m_phi; //锚点的旋转角度 };
#include "CMyAdjustPoint.h" #include <QCursor> #include <QGraphicsSceneMouseEvent> #include "CMyItemBase.h" #include "CMyLineItem.h" #include "CMyRect1Item.h" #include "CMyRect2Item.h" #include "CMyCirItem.h" #include "CMyConCirItem.h" #include "CMyChordItem.h" #include "CMyPieItem.h" #include "CMyPolygonItem.h" CMyAdjustPoint::CMyAdjustPoint(QAbstractGraphicsShapeItem *parent, QPointF p, double phi, POINT_TYPE type) :QAbstractGraphicsShapeItem(parent) , m_point(p) , m_phi(phi) , m_type(type) { this->setPos(m_point); //设置锚点的位置 this->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable); if (Center == type) { this->setCursor(Qt::SizeAllCursor); //中心点十字光标,用于拖动 } else { this->setCursor(Qt::PointingHandCursor); //边缘点手型光标,用于调整形状 } } CMyAdjustPoint::~CMyAdjustPoint() { } //设置锚点的角度 void CMyAdjustPoint::setPhi(double phi) { m_phi = phi; } QRectF CMyAdjustPoint::boundingRect() const { return QRectF(-g_pointSize / 2.0, -g_pointSize / 2.0, g_pointSize, g_pointSize); } //重绘事件 void CMyAdjustPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { this->setPos(m_point); //设置锚点的颜色 painter->setPen(QPen(Qt::GlobalColor(g_pointColor))); //设置锚点填充 if (g_bIsFillPoint) { painter->setBrush(QBrush(Qt::GlobalColor(g_pointColor), Qt::SolidPattern)); } painter->rotate(m_phi); //旋转 switch (m_type) { case Center:case Rotate: //中心锚点和旋转锚点,画成圆形 { painter->drawEllipse(QPointF(0, 0), g_pointSize / 2.0, g_pointSize / 2.0); break; } default: //其余画为矩形 { painter->drawRect(QRectF(-g_pointSize / 2.0, -g_pointSize / 2.0, g_pointSize, g_pointSize)); break; } } } //鼠标移动事件 void CMyAdjustPoint::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { //左键拖动和修改 if (event->buttons() == Qt::LeftButton) { qreal dx = event->scenePos().x() - event->lastScenePos().x(); qreal dy = event->scenePos().y() - event->lastScenePos().y(); CMyItemBase* item = static_cast<CMyItemBase *>(this->parentItem()); //获取图形 CMyItemBase::ITEM_TYPE itemType = item->getType(); //获取图形的类型 item->updateShowPos(); //实时更新坐标 //平移 if (Center == m_type) { item->moveBy(dx, dy); this->scene()->update(); } #pragma region 调整大小 //调整大小 switch (itemType) { #pragma region 直线 case CMyItemBase::Line: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyLineItem *line = dynamic_cast<CMyLineItem *>(item); switch (m_type) { case CMyAdjustPoint::EdgeStart: //调节起点 { line->setStart(m_point); break; } case CMyAdjustPoint::EdgeEnd: //调节终点 { line->setEnd(m_point); break; } default: { break; } } break; } #pragma endregion 直线 #pragma region 矩形 case CMyItemBase::Rect1: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyRect1Item *rect1 = dynamic_cast<CMyRect1Item *>(item); switch (m_type) { case CMyAdjustPoint::EdgeLU: //调节左上/右上/左下/右下角点 { rect1->setLU(m_point); break; } case CMyAdjustPoint::EdgeRU: { rect1->setRU(m_point); break; } case CMyAdjustPoint::EdgeLD: { rect1->setLD(m_point); break; } case CMyAdjustPoint::EdgeRD: { rect1->setRD(m_point); break; } default: { break; } } break; } #pragma endregion 矩形 #pragma region 旋转矩形 case CMyItemBase::Rect2: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyRect2Item *rect2 = dynamic_cast<CMyRect2Item *>(item); switch (m_type) { case CMyAdjustPoint::EdgeLU: //调节左上/右上/左下/右下角点 { rect2->setLU(m_point); break; } case CMyAdjustPoint::EdgeRU: { rect2->setRU(m_point); break; } case CMyAdjustPoint::EdgeLD: { rect2->setLD(m_point); break; } case CMyAdjustPoint::EdgeRD: { rect2->setRD(m_point); break; } case CMyAdjustPoint::Rotate: //旋转 { rect2->setPhi(m_point); break; } default: { break; } } break; } #pragma endregion 旋转矩形 #pragma region 圆 case CMyItemBase::Circle: { if (m_type == EdgeR) { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyCirItem *cir = dynamic_cast<CMyCirItem *>(item); cir->setR(m_point); } break; } #pragma endregion 圆 #pragma region 同心圆 case CMyItemBase::ConCircle: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyConCirItem *concir = dynamic_cast<CMyConCirItem *>(item); switch (m_type) { case CMyAdjustPoint::EdgeL: { concir->setR1(m_point); break; } case CMyAdjustPoint::EdgeR: { concir->setR2(m_point); break; } default: break; } break; } #pragma endregion 同心圆 #pragma region 弦 case CMyItemBase::Chord: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyChordItem *chord = dynamic_cast<CMyChordItem *>(item); if (m_type == EdgeR) { chord->setR(m_point); } break; } #pragma endregion 弦 #pragma region 饼 case CMyItemBase::Pie: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyPieItem *pie = dynamic_cast<CMyPieItem *>(item); if (m_type == EdgeR) { pie->setR(m_point); } break; } #pragma endregion 饼 #pragma region 多边形 case CMyItemBase::Polygon: { m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyPolygonItem *polygon = dynamic_cast<CMyPolygonItem *>(item); if (m_type == EdgeR) { polygon->setPolygonPoint(QPointF(event->lastScenePos().x(), event->lastScenePos().y()), QPointF(event->scenePos().x(), event->scenePos().y())); } break; } #pragma endregion 多边形 default: break; } #pragma endregion 调整大小 } } //鼠标双击事件,仅用于调整多边形 void CMyAdjustPoint::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { CMyItemBase* item = static_cast<CMyItemBase *>(this->parentItem()); CMyItemBase::ITEM_TYPE itemType = item->getType(); m_point = this->mapToParent(event->pos()); this->setPos(m_point); this->scene()->update(); CMyPolygonItem *polygon = dynamic_cast<CMyPolygonItem *>(item); if (event->buttons() == Qt::LeftButton) { if (CMyItemBase::Polygon == itemType&&EdgeR == m_type) { polygon->addPolygonPoint(m_point); //增点 } } else if (event->buttons() == Qt::RightButton) { if (CMyItemBase::Polygon == itemType&&EdgeR == m_type) { polygon->delPolygonPoint(m_point); //减点 } } }
#pragma once //弦 #include "CMyItemBase.h" class CMyChordItem : public CMyItemBase { Q_OBJECT public: CMyChordItem(QPointF center, double r,double phi); ~CMyChordItem(); void setR(QPointF p); //设置半径及角度 protected: QRectF boundingRect() const ; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPointF m_center; //弦的圆心 double m_r; //弦的半径 double m_phi; //弦的角度 };
#include "CMyChordItem.h" CMyChordItem::CMyChordItem(QPointF center, double r, double phi) :CMyItemBase(/*center, */ITEM_TYPE::Chord) { m_center = center; m_r = r; m_phi = phi; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(m_center.x() + m_r*cos(m_phi*PI / 180.0), m_center.y() + m_r*sin(m_phi*PI / 180.0)), 0, CMyAdjustPoint::EdgeR)); m_adjustPointList.append(new CMyAdjustPoint(this, m_center, 0, CMyAdjustPoint::Center)); } CMyChordItem::~CMyChordItem() { } //设置半径和角度 void CMyChordItem::setR(QPointF p) { m_r = hypot(p.x() - m_center.x(), p.y() - m_center.y()); //勾股公式 //计算角度 double theta = atan2((p.y() - m_center.y()), (p.x() - m_center.x())); m_phi = theta*180.0 / PI; if (m_phi>90) { m_phi = 180 - m_phi; } } QRectF CMyChordItem::boundingRect() const { return QRectF(m_center.x() - m_r, m_center.y() - m_r, m_center.x() + m_r, m_center.y() + m_r); } //重绘事件 void CMyChordItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } QRectF rect(m_center.x() - m_r, m_center.y() - m_r, m_r * 2, m_r * 2); painter->drawChord(rect, -m_phi * 16, (180 + m_phi * 2) * 16); }
#pragma once //圆 #include "CMyItemBase.h" class CMyCirItem : public CMyItemBase { Q_OBJECT public: CMyCirItem(QPointF center, double r); ~CMyCirItem(); void setR(QPointF p); //设置半径 protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPointF m_center; //圆心 double m_r; //半径 };
#include "CMyCirItem.h" CMyCirItem::CMyCirItem(QPointF center, double r) :CMyItemBase(/*center,*/ ITEM_TYPE::Circle) { m_center = center; m_r = r; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(m_center.x() + m_r, m_center.y()),0, CMyAdjustPoint::EdgeR)); m_adjustPointList.append(new CMyAdjustPoint(this, m_center, 0, CMyAdjustPoint::Center)); } CMyCirItem::~CMyCirItem() { } //设置半径 void CMyCirItem::setR(QPointF p) { m_r = hypot(p.x() - m_center.x(), p.y() - m_center.y()); } QRectF CMyCirItem::boundingRect() const { return QRectF(m_center.x() - m_r, m_center.y() - m_r, m_center.x() + m_r, m_center.y() + m_r); } //重绘事件 void CMyCirItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 QBrush brush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern); if (g_bIsFillShape) { painter->setBrush(brush); } painter->drawEllipse(m_center, m_r, m_r); }
#pragma once //同心圆 #include "CMyItemBase.h" class CMyConCirItem : public CMyItemBase { Q_OBJECT public: CMyConCirItem(QPointF center, double r1,double r2); ~CMyConCirItem(); void setR1(QPointF p); //设置半径 void setR2(QPointF p); //设置半径 protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPointF m_center; //圆心 double m_r1; //半径1 double m_r2; //半径2 };
#include "CMyConCirItem.h" CMyConCirItem::CMyConCirItem(QPointF center, double r1, double r2) :CMyItemBase(/*center, */ITEM_TYPE::ConCircle) { m_center = center; m_r1 = r1; m_r2 = r2; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(m_center.x() + m_r1, m_center.y()), 0, CMyAdjustPoint::EdgeL)); m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(m_center.x() + m_r2, m_center.y()), 0, CMyAdjustPoint::EdgeR)); m_adjustPointList.append(new CMyAdjustPoint(this, m_center, 0, CMyAdjustPoint::Center)); } CMyConCirItem::~CMyConCirItem() { } //设置半径1 void CMyConCirItem::setR1(QPointF p) { m_r1 = hypot(p.x() - m_center.x(), p.y() - m_center.y()); } //设置半径2 void CMyConCirItem::setR2(QPointF p) { m_r2= hypot(p.x() - m_center.x(), p.y() - m_center.y()); } QRectF CMyConCirItem::boundingRect() const { return QRectF(m_center.x() - m_r2, m_center.y() - m_r2, m_center.x() + m_r2, m_center.y() + m_r2); } //重绘事件 void CMyConCirItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } painter->setPen(pen); painter->drawEllipse(m_center, m_r1, m_r1); painter->drawEllipse(m_center, m_r2, m_r2); }
#pragma once //椭圆,椭圆和矩形很类似,唯一区别是draw函数 #include "CMyRect2Item.h" class CMyEllipseItem : public CMyRect2Item { Q_OBJECT public: CMyEllipseItem(double x, double y, double w, double h, double phi); ~CMyEllipseItem(); protected: virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; };
#include "CMyEllipseItem.h" CMyEllipseItem::CMyEllipseItem(double x, double y, double w, double h, double phi) :CMyRect2Item(x, y, w, h, phi) { } CMyEllipseItem::~CMyEllipseItem() { } void CMyEllipseItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } painter->setPen(pen); painter->translate(m_x, m_y); painter->rotate(m_phi); QRect rect(0, 0, m_width, m_height); painter->drawEllipse(rect); }
#pragma once //自定义图形的基类 #include <QObject> #include <QAbstractGraphicsShapeItem> #include "CMyAdjustPoint.h" #include <QGraphicsScene> #define PI 3.141592653 class CMyItemBase : public QObject, public QAbstractGraphicsShapeItem { Q_OBJECT public: enum ITEM_TYPE //图形的类型 { Line = 0, Rect1, Rect2, Circle, ConCircle, Polygon, RoundRect, Chord, Pie, Ellipse }; CMyItemBase(ITEM_TYPE type); ~CMyItemBase(); ITEM_TYPE getType(){ return m_type; } //获取图形的类型 void updateShowPos(); //刷新主界面显示的图形锚点坐标 public: QList<CMyAdjustPoint *> m_adjustPointList; //锚点列表 private: ITEM_TYPE m_type; //图形的类型 signals: void sg_updateCorners(int type, QList<QPointF>); //发送锚点坐标 };
#include "CMyItemBase.h" CMyItemBase::CMyItemBase(ITEM_TYPE type) :m_type(type) { } CMyItemBase::~CMyItemBase() { } //刷新显示的坐标 void CMyItemBase::updateShowPos() { QList<QPointF> pList; QList<QGraphicsItem *> items = this->scene()->items(); if (items.size() > 0) { for (int i = 0; i < m_adjustPointList.size(); i++) { //转换为图像中的坐标 QPointF sceneMousePos = this->mapToScene(m_adjustPointList.at(i)->getPoint()); QPointF itemMousePos = items[items.size() - 1]->mapFromScene(sceneMousePos); pList << itemMousePos; } } emit sg_updateCorners(m_type, pList); }
#pragma once //直线图形 #include "CMyItemBase.h" class CMyLineItem : public CMyItemBase { Q_OBJECT public: CMyLineItem(QPointF pStart, QPointF pEnd); ~CMyLineItem(); void setStart(QPointF p); //设置起点 void setEnd(QPointF p); //设置终点 protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPointF m_pStart; //起止点 QPointF m_pEnd; };
#include "CMyLineItem.h" CMyLineItem::CMyLineItem(QPointF pStart, QPointF pEnd) :CMyItemBase(ITEM_TYPE::Line) { m_pStart = pStart; m_pEnd = pEnd; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, m_pStart, 0, CMyAdjustPoint::EdgeStart)); m_adjustPointList.append(new CMyAdjustPoint(this, m_pEnd, 0, CMyAdjustPoint::EdgeEnd)); m_adjustPointList.append(new CMyAdjustPoint(this, (m_pStart + m_pEnd) / 2.0, 0, CMyAdjustPoint::Center)); } CMyLineItem::~CMyLineItem() { } //设置起点 void CMyLineItem::setStart(QPointF p) { m_pStart = p; m_adjustPointList.at(2)->setPoint((m_pStart + m_pEnd) / 2.0); //重设中心锚点 } //设置终点 void CMyLineItem::setEnd(QPointF p) { m_pEnd = p; m_adjustPointList.at(2)->setPoint((m_pStart + m_pEnd) / 2.0); //重设中心锚点 } QRectF CMyLineItem::boundingRect() const { return QRectF(m_pStart.x(), m_pStart.y(), m_pEnd.x() - m_pStart.x(), m_pEnd.y() - m_pStart.y()); } //重绘事件 void CMyLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); QLineF line(m_pStart.x(), m_pStart.y(), m_pEnd.x(), m_pEnd.y()); painter->drawLine(line); }
#pragma once //饼形 #include "CMyItemBase.h" class CMyPieItem : public CMyItemBase { Q_OBJECT public: CMyPieItem(QPointF center, double r, double phi); ~CMyPieItem(); void setR(QPointF p); //设置半径及角度 protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QPointF m_center; //圆心 double m_r; //半径 double m_phi; //角度 };
#include "CMyPieItem.h" CMyPieItem::CMyPieItem(QPointF center, double r, double phi) :CMyItemBase(ITEM_TYPE::Pie) { m_center = center; m_r = r; m_phi = phi; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(m_center.x() + m_r*cos(m_phi*PI / 180.0), m_center.y() + m_r*sin(m_phi*PI / 180.0)), 0, CMyAdjustPoint::EdgeR)); m_adjustPointList.append(new CMyAdjustPoint(this, m_center, 0, CMyAdjustPoint::Center)); } CMyPieItem::~CMyPieItem() { } //设置半径和角度 void CMyPieItem::setR(QPointF p) { m_r = hypot(p.x() - m_center.x(), p.y() - m_center.y()); double theta = atan2((p.y() - m_center.y()), (p.x() - m_center.x())); m_phi = theta*180.0 / PI; if (m_phi>0) { m_phi = -360 + m_phi; } } QRectF CMyPieItem::boundingRect() const { return QRectF(m_center.x() - m_r, m_center.y() - m_r, m_center.x() + m_r, m_center.y() + m_r); } //重绘事件 void CMyPieItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } QRectF rect(m_center.x() - m_r, m_center.y() - m_r, m_r * 2, m_r * 2); painter->drawPie(rect,0, -m_phi * 16); }
#pragma once //多边形 #include "CMyItemBase.h" class CMyPolygonItem : public CMyItemBase { Q_OBJECT public: CMyPolygonItem(); ~CMyPolygonItem(); QPointF calcCenter(QList<QPointF> list); //计算中心 void calcMaxLength(); //计算极径,作用是确定在boundingRect中刷新的区域 void setPolygonPoint(QPointF origin, QPointF end); //移动锚点时刷新重心和极径 void addPolygonPoint(QPointF origin); //左键双击锚点时加点 void delPolygonPoint(QPointF origin); //右键双击锚点时减点 protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public slots: void sls_addPoint(QPointF, QList<QPointF>, bool); //添加点 private: QPointF m_center; //重心 double m_length; //极径 bool m_isFinished; //是否绘制完成,右键点击时表示完成 };
#include "CMyPolygonItem.h" CMyPolygonItem::CMyPolygonItem() : CMyItemBase(ITEM_TYPE::Polygon) { m_isFinished = false; } CMyPolygonItem::~CMyPolygonItem() { } //计算重心 QPointF CMyPolygonItem::calcCenter(QList<QPointF> list) { double x = 0; double y = 0; for (auto &temp : list) { x += temp.x(); y += temp.y(); } x = x / list.size(); y = y / list.size(); return QPointF(x, y); } //计算极径 void CMyPolygonItem::calcMaxLength() { m_length = 0; for (int i = 0; i < m_adjustPointList.size(); i++) { double dist = hypot(m_adjustPointList.at(i)->x() - m_center.x(), m_adjustPointList.at(i)->y() - m_center.y()); m_length = dist > m_length ? dist : m_length; } } //移动锚点时刷新重心和极径 void CMyPolygonItem::setPolygonPoint(QPointF origin, QPointF end) { QList<QPointF> list; for (auto &temp : m_adjustPointList) { if (temp->getPoint() == origin) { temp->setPoint(end); } list.append(temp->getPoint()); } m_center = calcCenter(list); m_adjustPointList.at(m_adjustPointList.size() - 1)->setPoint(m_center); calcMaxLength(); } //左键双击锚点时加点 void CMyPolygonItem::addPolygonPoint(QPointF origin) { if (m_isFinished) { QList<QPointF> list; QPointF addPoint; int index = 0; for (int i = 0; i < m_adjustPointList.size();i++) { if (m_adjustPointList.at(i)->getPoint() == origin) { index = i; if (i == m_adjustPointList.size()-2) { double x = (m_adjustPointList.at(i)->getPoint().x() + m_adjustPointList.at(0)->getPoint().x()) / 2.0; double y = (m_adjustPointList.at(i)->getPoint().y() + m_adjustPointList.at(0)->getPoint().y()) / 2.0; addPoint.setX(x); addPoint.setY(y); } else { double x = (m_adjustPointList.at(i)->getPoint().x() + m_adjustPointList.at(i + 1)->getPoint().x()) / 2.0; double y = (m_adjustPointList.at(i)->getPoint().y() + m_adjustPointList.at(i + 1)->getPoint().y()) / 2.0; addPoint.setX(x); addPoint.setY(y); } } list.append(m_adjustPointList.at(i)->getPoint()); } m_adjustPointList.insert(index + 1, new CMyAdjustPoint(this, addPoint, 0, CMyAdjustPoint::EdgeR)); m_center = calcCenter(list); m_adjustPointList.at(m_adjustPointList.size() - 1)->setPoint(m_center); calcMaxLength(); } } //右键锚点时减点 void CMyPolygonItem::delPolygonPoint(QPointF origin) { if (m_isFinished) { QList<QPointF> list; for (int i = 0; i < m_adjustPointList.size(); i++) { if (m_adjustPointList.at(i)->getPoint() == origin) { CMyAdjustPoint *p= m_adjustPointList.takeAt(i); delete p; p = NULL; } } for (int i = 0; i < m_adjustPointList.size(); i++) { list.append(m_adjustPointList.at(i)->getPoint()); } m_center = calcCenter(list); m_adjustPointList.at(m_adjustPointList.size() - 1)->setPoint(m_center); calcMaxLength(); } } QRectF CMyPolygonItem::boundingRect() const { return QRectF(m_center.x() - m_length, m_center.y() - m_length, m_length * 2, m_length * 2); } void CMyPolygonItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } if (m_isFinished) { QVector<QPointF> pointV; for (int i = 0; i < m_adjustPointList.size()-1; i++) { pointV.append(m_adjustPointList.at(i)->getPoint()); } QPolygonF polygon(pointV); painter->drawPolygon(polygon); } else { for (int i = 1; i < m_adjustPointList.size(); i++) { painter->drawLine(m_adjustPointList.at(i - 1)->getPoint(), m_adjustPointList.at(i)->getPoint()); } } } //添加点 void CMyPolygonItem::sls_addPoint(QPointF p, QList<QPointF> pointList, bool isFinished) { if (!m_isFinished) { m_center = calcCenter(pointList); calcMaxLength(); if (isFinished) { m_adjustPointList.append(new CMyAdjustPoint(this, m_center, 0, CMyAdjustPoint::Center)); m_isFinished = true; } else { m_adjustPointList.append(new CMyAdjustPoint(this, p, 0, CMyAdjustPoint::EdgeR)); } this->update(); } }
#pragma once //矩形 #include "CMyItemBase.h" class CMyRect1Item : public CMyItemBase { Q_OBJECT public: CMyRect1Item(double x,double y,double w,double h); ~CMyRect1Item(); void setLU(QPointF p); //设置锚点 void setRU(QPointF p); void setLD(QPointF p); void setRD(QPointF p); protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public: double m_x, m_y, m_width, m_height; };
#include "CMyRect1Item.h" CMyRect1Item::CMyRect1Item(double x, double y, double w, double h) :CMyItemBase(ITEM_TYPE::Rect1) { m_x = x; m_y = y; m_width = w; m_height = h; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x, y), 0, CMyAdjustPoint::EdgeLU)); m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x + w, y), 0, CMyAdjustPoint::EdgeRU)); m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x, y + h), 0, CMyAdjustPoint::EdgeLD)); m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x + w, y + h), 0, CMyAdjustPoint::EdgeRD)); m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x + w / 2, y + h / 2), 0, CMyAdjustPoint::Center)); } CMyRect1Item::~CMyRect1Item() { } //设置角点 void CMyRect1Item::setLU(QPointF p) { m_width = m_x + m_width - p.x(); m_height = m_y + m_height - p.y(); m_x = p.x(); m_y = p.y(); m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(1)->setPoint(QPointF(m_x + m_width, m_y)); m_adjustPointList.at(2)->setPoint(QPointF(m_x, m_y + m_height)); m_adjustPointList.at(3)->setPoint(QPointF(m_x + m_width, m_y + m_height)); m_adjustPointList.at(4)->setPoint(QPointF(m_x + m_width / 2, m_y + m_height / 2)); } void CMyRect1Item::setRU(QPointF p) { m_width = p.x() - m_x; m_height = m_height + m_y - p.y(); m_y = p.y(); m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(1)->setPoint(QPointF(m_x + m_width, m_y)); m_adjustPointList.at(2)->setPoint(QPointF(m_x, m_y + m_height)); m_adjustPointList.at(3)->setPoint(QPointF(m_x + m_width, m_y + m_height)); m_adjustPointList.at(4)->setPoint(QPointF(m_x + m_width / 2, m_y + m_height / 2)); } void CMyRect1Item::setLD(QPointF p) { m_width = m_x + m_width - p.x(); m_height = p.y() - m_y; m_x = p.x(); m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(1)->setPoint(QPointF(m_x + m_width, m_y)); m_adjustPointList.at(2)->setPoint(QPointF(m_x, m_y + m_height)); m_adjustPointList.at(3)->setPoint(QPointF(m_x + m_width, m_y + m_height)); m_adjustPointList.at(4)->setPoint(QPointF(m_x + m_width / 2, m_y + m_height / 2)); } void CMyRect1Item::setRD(QPointF p) { m_width = p.x() - m_x; m_height = p.y() - m_y; m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(1)->setPoint(QPointF(m_x + m_width, m_y)); m_adjustPointList.at(2)->setPoint(QPointF(m_x, m_y + m_height)); m_adjustPointList.at(3)->setPoint(QPointF(m_x + m_width, m_y + m_height)); m_adjustPointList.at(4)->setPoint(QPointF(m_x + m_width / 2, m_y + m_height / 2)); } QRectF CMyRect1Item::boundingRect() const { return QRectF(m_x, m_y, m_width, m_height); } //重绘事件 void CMyRect1Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } QRect rect(m_x,m_y, m_width, m_height); painter->drawRect(rect); }
#pragma once //旋转矩形 #include "CMyItemBase.h" class CMyRect2Item : public CMyItemBase { Q_OBJECT public: CMyRect2Item(double x, double y, double w, double h,double phi); ~CMyRect2Item(); //根据参数计算各个锚点和中心 QPointF calcRU(); QPointF calcLD(); QPointF calcRD(); QPointF calcCenter(); QPointF calcRotate(); void setLU(QPointF p); void setRU(QPointF p); void setLD(QPointF p); void setRD(QPointF p); void setPhi(QPointF p); protected: QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public: double m_x, m_y, m_width, m_height,m_phi; };
#include "CMyRect2Item.h" CMyRect2Item::CMyRect2Item(double x, double y, double w, double h, double phi) :CMyItemBase(ITEM_TYPE::Rect2) { m_x = x; m_y = y; m_width = w; m_height = h; m_phi = phi; //添加锚点 m_adjustPointList.append(new CMyAdjustPoint(this, QPointF(x, y), phi, CMyAdjustPoint::EdgeLU)); m_adjustPointList.append(new CMyAdjustPoint(this, calcRU(), phi, CMyAdjustPoint::EdgeRU)); m_adjustPointList.append(new CMyAdjustPoint(this, calcLD(), phi, CMyAdjustPoint::EdgeLD)); m_adjustPointList.append(new CMyAdjustPoint(this, calcRD(), phi, CMyAdjustPoint::EdgeRD)); m_adjustPointList.append(new CMyAdjustPoint(this, calcCenter(), 0, CMyAdjustPoint::Center)); m_adjustPointList.append(new CMyAdjustPoint(this, calcRotate(), 0, CMyAdjustPoint::Rotate)); } CMyRect2Item::~CMyRect2Item() { } //设置锚点 void CMyRect2Item::setLU(QPointF p) { double theta = atan2((p.y() - m_y), (p.x() - m_x)); double delta = theta - m_phi*PI / 180.0; double L = hypot(p.x() - m_x, p.y() - m_y); m_x = p.x(); m_y = p.y(); m_width = m_width - L*cos(delta); m_height = m_height - L*sin(delta); m_adjustPointList.at(1)->setPoint(calcRU()); m_adjustPointList.at(2)->setPoint(calcLD()); m_adjustPointList.at(4)->setPoint(calcCenter()); m_adjustPointList.at(5)->setPoint(calcRotate()); update(); } void CMyRect2Item::setRU(QPointF p) { double theta = atan2((p.y() - calcRU().y()), (p.x() - calcRU().x())); double delta = theta - m_phi*PI / 180.0; double L = hypot(p.x() - calcRU().x(), p.y() - calcRU().y()); m_width = m_width + L*cos(delta); m_height = m_height - L*sin(delta); m_x = m_x + L*sin(delta)*sin(-m_phi*PI / 180.0); m_y = m_y + L*sin(delta)*cos(-m_phi*PI / 180.0); m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(3)->setPoint(calcRD()); m_adjustPointList.at(4)->setPoint(calcCenter()); m_adjustPointList.at(5)->setPoint(calcRotate()); update(); } void CMyRect2Item::setLD(QPointF p) { double theta = atan2((p.y() - calcLD().y()), (p.x() - calcLD().x())); double delta = theta - m_phi*PI / 180.0; double L = hypot(p.x() - calcLD().x(), p.y() - calcLD().y()); m_width = m_width - L*cos(delta); m_height = m_height + L*sin(delta); m_x = m_x + L*cos(delta)*cos(-m_phi*PI / 180.0); m_y = m_y - L*cos(delta)*sin(-m_phi*PI / 180.0); m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(3)->setPoint(calcRD()); m_adjustPointList.at(4)->setPoint(calcCenter()); m_adjustPointList.at(5)->setPoint(calcRotate()); update(); } void CMyRect2Item::setRD(QPointF p) { double theta = atan2((p.y() - calcRD().y()), (p.x() - calcRD().x())); double delta = theta - m_phi*PI / 180.0; double L = hypot(p.x() - calcRD().x(), p.y() - calcRD().y()); m_width = m_width + L*cos(delta); m_height = m_height + L*sin(delta); m_adjustPointList.at(1)->setPoint(calcRU()); m_adjustPointList.at(2)->setPoint(calcLD()); m_adjustPointList.at(4)->setPoint(calcCenter()); m_adjustPointList.at(5)->setPoint(calcRotate()); update(); } void CMyRect2Item::setPhi(QPointF p) { QPointF center = calcCenter(); double theta = atan2((p.y() - calcCenter().y()), (p.x() - calcCenter().x())); m_phi = theta*180.0 / PI; m_x = center.x() - (m_height*sin(-m_phi*PI / 180.0) + m_width*cos(-m_phi*PI / 180.0)) / 2.0; m_y = center.y() - (m_height*cos(-m_phi*PI / 180.0) - m_width*sin(-m_phi*PI / 180.0)) / 2.0; m_adjustPointList.at(0)->setPoint(QPointF(m_x, m_y)); m_adjustPointList.at(1)->setPoint(calcRU()); m_adjustPointList.at(2)->setPoint(calcLD()); m_adjustPointList.at(3)->setPoint(calcRD()); m_adjustPointList.at(0)->setPhi(m_phi); m_adjustPointList.at(1)->setPhi(m_phi); m_adjustPointList.at(2)->setPhi(m_phi); m_adjustPointList.at(3)->setPhi(m_phi); update(); } QRectF CMyRect2Item::boundingRect() const { return QRectF(m_x, m_y, m_width, m_height); } //重绘事件 void CMyRect2Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } painter->translate(m_x, m_y); painter->rotate(m_phi); QRect rect(0, 0, m_width, m_height); painter->drawRect(rect); } //根据参数计算各个锚点和中心 QPointF CMyRect2Item::calcRU() { return QPointF(m_x + m_width*cos(-m_phi*PI / 180.0), m_y - m_width*sin(-m_phi*PI / 180.0)); } QPointF CMyRect2Item::calcLD() { return QPointF(m_x + m_height*sin(-m_phi*PI / 180.0), m_y + m_height*cos(-m_phi*PI / 180.0)); } QPointF CMyRect2Item::calcRD() { return QPointF(m_x + m_height*sin(-m_phi*PI / 180.0) + m_width*cos(-m_phi*PI / 180.0), m_y + m_height*cos(-m_phi*PI / 180.0) - m_width*sin(-m_phi*PI / 180.0)); } QPointF CMyRect2Item::calcCenter() { return QPointF(m_x + (m_height*sin(-m_phi*PI / 180.0) + m_width*cos(-m_phi*PI / 180.0)) / 2.0, m_y + (m_height*cos(-m_phi*PI / 180.0) - m_width*sin(-m_phi*PI / 180.0)) / 2.0); } QPointF CMyRect2Item::calcRotate() { return QPointF(m_x + m_width*cos(-m_phi*PI / 180.0) + m_height*sin(-m_phi*PI / 180.0) / 2.0 + 10 * cos(-m_phi*PI / 180.0), m_y - m_width*sin(-m_phi*PI / 180.0) + m_height*cos(-m_phi*PI / 180.0) / 2.0 - 10 * sin(-m_phi*PI / 180.0)); }
#pragma once //圆角矩形1 #include "CMyRect1Item.h" class CMyRoundRect1Item : public CMyRect1Item { Q_OBJECT public: CMyRoundRect1Item(double x, double y, double w, double h); ~CMyRoundRect1Item(); protected: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); };
#include "CMyRoundRect1Item.h" CMyRoundRect1Item::CMyRoundRect1Item(double x, double y, double w, double h) : CMyRect1Item(x, y, w, h) { } CMyRoundRect1Item::~CMyRoundRect1Item() { } //重绘事件 void CMyRoundRect1Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } QRect rect(m_x, m_y, m_width, m_height); painter->drawRoundedRect(rect, m_height / 2.0, m_height / 2.0); }
#pragma once //旋转圆角矩形 #include "CMyRect2Item.h" class CMyRoundRect2Item : public CMyRect2Item { Q_OBJECT public: CMyRoundRect2Item(double x, double y, double w, double h, double phi); ~CMyRoundRect2Item(); protected: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); };
#include "CMyRoundRect2Item.h" CMyRoundRect2Item::CMyRoundRect2Item(double x, double y, double w, double h, double phi) :CMyRect2Item(x, y, w, h, phi) { } CMyRoundRect2Item::~CMyRoundRect2Item() { } void CMyRoundRect2Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setRenderHint(QPainter::Antialiasing, true); //设置反走样,防锯齿 //设置画笔 QPen pen(Qt::GlobalColor(g_shapeColor), g_shapeLineW, Qt::SolidLine); painter->setPen(pen); //设置填充 if (g_bIsFillShape) { painter->setBrush(QBrush(Qt::GlobalColor(g_shapeColor), Qt::SolidPattern)); } painter->translate(m_x, m_y); painter->rotate(m_phi); QRect rect(0, 0, m_width, m_height); painter->drawRoundedRect(rect, m_height / 2.0, m_height / 2.0); }
#pragma execution_character_set("utf-8")
extern int g_shapeColor;
extern int g_shapeLineW;
extern int g_pointColor;
extern int g_pointSize;
extern bool g_bIsFillShape;
extern bool g_bIsFillPoint;
#include "globalVar.h"
int g_shapeColor = 0; //图形颜色
int g_shapeLineW = 0; //图形宽度
int g_pointColor = 0; //锚点颜色
int g_pointSize = 0; //锚点尺寸
bool g_bIsFillShape = false; //是否填充形状
bool g_bIsFillPoint = false; //是否填充锚点
#pragma once #include <QtWidgets/QMainWindow> #include "ui_MainWindow.h" #include <QGraphicsScene> #include <QGraphicsItem> #include "MyGraphicsScene.h" #include "CMyLineItem.h" #include "CMyRect1Item.h" #include "CMyRect2Item.h" #include "CMyCirItem.h" #include "CMyConCirItem.h" #include "CMyRoundRect1Item.h" #include "CMyRoundRect2Item.h" #include "CMyChordItem.h" #include "CMyPieItem.h" #include "CMyEllipseItem.h" #include "CMyPolygonItem.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = Q_NULLPTR); ~MainWindow(); void frmInit(); //界面初始化 void paramInit(); //参数初始化 private slots: void on_btn_loadImg_clicked(); //加载图片 void on_btn_drawLine_clicked(); //绘制直线 void on_btn_drawRect1_clicked(); //绘制正矩形 void on_btn_drawRect2_clicked(); //绘制旋转矩形 void on_btn_drawCir_clicked(); //绘制圆形 void on_btn_drawConCir_clicked(); //绘制同心圆 void on_btn_drawPolygon_clicked(); //绘制多边形 void on_btn_drawRoundRect1_clicked(); //绘制圆角矩形1 void on_btn_drawRoundRect2_clicked(); //绘制圆角矩形2 void on_btn_drawChord_clicked(); //绘制弦 void on_btn_drawPie_clicked(); //绘制饼 void on_btn_drawEllipse_clicked(); //绘制椭圆 void on_cbBox_shapeColor_currentIndexChanged(int); //改变形状颜色 void on_cbBox_pointColor_currentIndexChanged(int); //改变锚点颜色 void on_cbBox_shapeLineW_currentIndexChanged(int); //改变形状线宽 void on_cbBox_pointSize_currentIndexChanged(int); //改变锚点大小 void on_ckBox_fillShape_stateChanged(int); //形状填充 void on_ckBox_fillPoint_stateChanged(int); //锚点填充 void on_btn_clear_clicked(); //清空 void sls_updateShowPos(int, QList<QPointF>); //显示图形的锚点坐标 private: QGraphicsPixmapItem *m_imgItem; MyGraphicsScene *m_graphicsScene; Ui::MainWindowClass ui; };
#include "MainWindow.h" #include <QDir> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_graphicsScene(NULL) { ui.setupUi(this); frmInit(); paramInit(); } MainWindow::~MainWindow() { if (m_imgItem!=NULL) { delete m_imgItem; m_imgItem = NULL; } delete m_graphicsScene; m_graphicsScene = NULL; } void MainWindow::frmInit() { QMap<QString, int> shapeColorMap; shapeColorMap.insert("白色", Qt::white); shapeColorMap.insert("黑色", Qt::black); shapeColorMap.insert("红色", Qt::red); shapeColorMap.insert("绿色", Qt::green); shapeColorMap.insert("蓝色", Qt::blue); shapeColorMap.insert("黄色", Qt::yellow); QMap<QString, int>::Iterator it = shapeColorMap.begin(); while (it != shapeColorMap.end()) { QPixmap pix(20, 20); pix.fill(Qt::GlobalColor(it.value())); ui.cbBox_shapeColor->addItem(QIcon(pix), it.key(), it.value()); //形状颜色 ui.cbBox_pointColor->addItem(QIcon(pix), it.key(), it.value()); //锚点颜色 it++; } ui.cbBox_shapeColor->setCurrentIndex(1); ui.cbBox_pointColor->setCurrentIndex(2); ui.cbBox_shapeLineW->setCurrentIndex(1); ui.cbBox_pointSize->setCurrentIndex(2); } //参数初始化 void MainWindow::paramInit() { m_imgItem = new QGraphicsPixmapItem; //图像元素 m_graphicsScene = new MyGraphicsScene; //自定义场景 m_graphicsScene->addItem(m_imgItem); m_graphicsScene->setBackgroundBrush(Qt::black); ui.graphicsView->setScene(m_graphicsScene); //鼠标移动时,显示坐标 connect(ui.graphicsView, &MyGraphicsView::updatePos, this, [=](QPointF pos) { QString str = QString("coordinate: ") + "(" + QString::number(int(pos.x())) + "," + QString::number(int(pos.y())) + ")"; ui.label_pos->setText(str); }); } //加载图片 void MainWindow::on_btn_loadImg_clicked() { QList<QGraphicsItem *> items=m_graphicsScene->items(); if (items.size() == 0) { m_imgItem = new QGraphicsPixmapItem; m_graphicsScene->addItem(m_imgItem); } QImage img("./image.bmp"); m_imgItem->setPixmap(QPixmap::fromImage(img)); ui.graphicsView->fitInView(m_imgItem, Qt::KeepAspectRatio); } //绘制直线 void MainWindow::on_btn_drawLine_clicked() { CMyLineItem *line = new CMyLineItem(QPointF(20, 20), QPointF(100, 100)); m_graphicsScene->addItem(line); connect(line, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制正矩形 void MainWindow::on_btn_drawRect1_clicked() { CMyRect1Item *rect = new CMyRect1Item(20, 20, 100, 100); m_graphicsScene->addItem(rect); connect(rect, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制旋转矩形 void MainWindow::on_btn_drawRect2_clicked() { CMyRect2Item *rect2 = new CMyRect2Item(20, 20, 100, 50, -30); m_graphicsScene->addItem(rect2); connect(rect2, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制圆形 void MainWindow::on_btn_drawCir_clicked() { CMyCirItem *cir = new CMyCirItem(QPointF(20, 20), 100); m_graphicsScene->addItem(cir); connect(cir, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制同心圆 void MainWindow::on_btn_drawConCir_clicked() { CMyConCirItem *concir = new CMyConCirItem(QPointF(20, 20), 100, 150); m_graphicsScene->addItem(concir); connect(concir, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制多边形 void MainWindow::on_btn_drawPolygon_clicked() { m_graphicsScene->startDrawPolygon(); CMyPolygonItem *polygon = new CMyPolygonItem(); m_graphicsScene->addItem(polygon); connect(polygon, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); connect(m_graphicsScene, SIGNAL(sg_updatePoint(QPointF, QList<QPointF>, bool)), polygon, SLOT(sls_addPoint(QPointF, QList<QPointF>, bool))); } //绘制圆角矩形1 void MainWindow::on_btn_drawRoundRect1_clicked() { CMyRoundRect1Item *roundRect1 = new CMyRoundRect1Item(20, 20, 100, 100); m_graphicsScene->addItem(roundRect1); connect(roundRect1, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制圆角矩形2 void MainWindow::on_btn_drawRoundRect2_clicked() { CMyRoundRect2Item *roundRect2 = new CMyRoundRect2Item(20, 20, 100, 50, -30); m_graphicsScene->addItem(roundRect2); connect(roundRect2, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制弦 void MainWindow::on_btn_drawChord_clicked() { CMyChordItem *chord = new CMyChordItem(QPointF(20, 20), 100, -30); m_graphicsScene->addItem(chord); connect(chord, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制饼 void MainWindow::on_btn_drawPie_clicked() { CMyPieItem *pie = new CMyPieItem(QPointF(20, 20), 100, -30); m_graphicsScene->addItem(pie); connect(pie, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //绘制椭圆 void MainWindow::on_btn_drawEllipse_clicked() { CMyEllipseItem *ellipse = new CMyEllipseItem(20, 20, 100, 50, -30); m_graphicsScene->addItem(ellipse); connect(ellipse, SIGNAL(sg_updateCorners(int, QList<QPointF>)), this, SLOT(sls_updateShowPos(int, QList<QPointF>))); m_graphicsScene->update(); } //改变形状颜色 void MainWindow::on_cbBox_shapeColor_currentIndexChanged(int index) { g_shapeColor = ui.cbBox_shapeColor->itemData(index).toInt(); if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //改变锚点颜色 void MainWindow::on_cbBox_pointColor_currentIndexChanged(int index) { g_pointColor = ui.cbBox_pointColor->itemData(index).toInt(); if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //改变形状线宽 void MainWindow::on_cbBox_shapeLineW_currentIndexChanged(int) { g_shapeLineW = ui.cbBox_shapeLineW->currentText().toInt(); if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //改变锚点大小 void MainWindow::on_cbBox_pointSize_currentIndexChanged(int) { g_pointSize = ui.cbBox_pointSize->currentText().toInt(); if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //形状填充 void MainWindow::on_ckBox_fillShape_stateChanged(int flg) { g_bIsFillShape = flg; if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //锚点填充 void MainWindow::on_ckBox_fillPoint_stateChanged(int flg) { g_bIsFillPoint = flg; if (m_graphicsScene != NULL) { m_graphicsScene->update(); } } //清空 void MainWindow::on_btn_clear_clicked() { m_graphicsScene->clear(); } void MainWindow::sls_updateShowPos(int type, QList<QPointF> pList) { ui.textEdit->clear(); for (int i = 0; i < pList.size(); i++) { ui.textEdit->append(QString("(x%1:%2,y%3:%4)").arg(i + 1).arg(int(pList[i].x())).arg(i + 1).arg(int(pList[i].y()))); } }
#pragma once #include <QGraphicsScene> class MyGraphicsScene : public QGraphicsScene { Q_OBJECT public: MyGraphicsScene(QObject *parent=NULL); ~MyGraphicsScene(); void startDrawPolygon(); //开始绘制多边形 void mousePressEvent(QGraphicsSceneMouseEvent *event); signals: void sg_updatePoint(QPointF p, QList<QPointF> list, bool isCenter); void sg_finishDrawPolygon(); public: QList<QPointF> m_list; bool m_bIsDrawingPolygon; };
#include "MyGraphicsScene.h" #include <QGraphicsSceneMouseEvent> MyGraphicsScene::MyGraphicsScene(QObject *parent) : QGraphicsScene(parent) { m_bIsDrawingPolygon = false; } MyGraphicsScene::~MyGraphicsScene() { } //开始绘制多边形 void MyGraphicsScene::startDrawPolygon() { m_bIsDrawingPolygon = true; } void MyGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (m_bIsDrawingPolygon) { QPointF p(event->scenePos().x(), event->scenePos().y()); switch (event->buttons()) { case Qt::LeftButton: { m_list.push_back(p); emit sg_updatePoint(p, m_list, false); break; } case Qt::RightButton: { if (m_list.size() >= 3) { emit sg_updatePoint(p, m_list, true); emit sg_finishDrawPolygon(); m_bIsDrawingPolygon = false; m_list.clear(); } break; } default: break; } } else { QGraphicsScene::mousePressEvent(event); } }
#pragma once #include <QGraphicsView> class MyGraphicsView : public QGraphicsView { Q_OBJECT public: MyGraphicsView(QWidget *parent = NULL); ~MyGraphicsView(); void mousePressEvent(QMouseEvent *ev); //鼠标按下事件 void mouseReleaseEvent(QMouseEvent *ev); //鼠标松开事件 void mouseMoveEvent(QMouseEvent *ev); //鼠标移动事件 void wheelEvent(QWheelEvent *ev); //缩放函数 void translate(QPointF); //平移函数 private: bool m_bIsMove; //是否进行平移 QPoint m_pressedPos; //平移时鼠标点下的位置 double m_zoomDelta; //缩放因子 signals: void updatePos(QPointF); };
#include "MyGraphicsView.h" #include <QMouseEvent> #include <QGraphicsItem> MyGraphicsView::MyGraphicsView(QWidget *parent) : QGraphicsView(parent) { m_bIsMove = false; m_zoomDelta = 0.1; setSceneRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX); setDragMode(NoDrag); // 去掉滚动条 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setResizeAnchor(QGraphicsView::AnchorUnderMouse); } MyGraphicsView::~MyGraphicsView() { } //鼠标按下事件 void MyGraphicsView::mousePressEvent(QMouseEvent *ev) { //右键平移 if (ev->button()==Qt::RightButton) { m_bIsMove = true; m_pressedPos = ev->pos(); } QGraphicsView::mousePressEvent(ev); } //鼠标松开事件 void MyGraphicsView::mouseReleaseEvent(QMouseEvent *ev) { //右键平移 if (ev->button() == Qt::RightButton) { m_bIsMove = false; } QGraphicsView::mouseReleaseEvent(ev); } //鼠标移动事件 void MyGraphicsView::mouseMoveEvent(QMouseEvent *ev) { if (m_bIsMove) { QPointF mouseDelta =ev->pos() - m_pressedPos; translate(mouseDelta); } m_pressedPos = ev->pos(); QList<QGraphicsItem *> item = this->scene()->items(ev->pos()); if (item.size()>0) { QPointF sceneMousePos = this->mapToScene(ev->pos()); QPointF itemMousePos = item[item.size()-1]->mapFromScene(sceneMousePos); emit updatePos(itemMousePos); } else { QPointF p(0, 0); emit updatePos(p); } QGraphicsView::mouseMoveEvent(ev); } //缩放函数 void MyGraphicsView::wheelEvent(QWheelEvent *ev) { // 滚轮的滚动量 QPoint scrollAmount = ev->angleDelta(); // 正值表示滚轮远离使用者(放大),负值表示朝向使用者(缩小) double zoomFactor = 0; zoomFactor = scrollAmount.y() > 0 ? (1 + m_zoomDelta) : (1 - m_zoomDelta); // 防止太小或过大 qreal factor = transform().scale(zoomFactor, zoomFactor).mapRect(QRectF(0, 0, 1, 1)).width(); if (factor < 0.07 || factor > 100) { return; } scale(zoomFactor, zoomFactor); } //平移函数 void MyGraphicsView::translate(QPointF delta) { // view 根据鼠标下的点做为锚点来定位 scene setTransformationAnchor(QGraphicsView::AnchorUnderMouse); QPoint newCenter(viewport()->rect().width() / 2 - delta.x(), viewport()->rect().height() / 2 - delta.y()); centerOn(mapToScene(newCenter)); // scene 在 view 的中心点做为锚点 setTransformationAnchor(QGraphicsView::AnchorViewCenter); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。