赞
踩
网上有很多关于这三个的资料,这方面的功能不做过多的描述,仅仅将在做小Demo过程中遇到的问题做下记录,下面是Demo的界面图:
Demo的初衷是不想每次使用QGraphicsView和QGraphicsScene都重写,可以直接拿来使用,后来慢慢加了一些图形项,因为其实是为了熟悉QGpaphicsXX,所以目前只加了3种(正矩形,旋转矩形、圆),刚好这个Demo也练习了一种设计模式——工厂模式,现在就讲些步骤及遇到的问题(只贴关键的代码,整体代码看最后下载链接):
一、以鼠标为中心进行缩放
QGraphicsView和QGraphicsScene(后面简称View和Scene)都是要重写的,这一部分我主要放在View中实现,主要重写滚轮事件 wheelEvent(QWheelEvent * event),代码(部分)如下:
- void MyGraphicsView::wheelEvent(QWheelEvent * event)
- {
- if (this->scene()->items().size() == 0)
- return;
- QPointF curPoint = event->pos();
- QPointF scenePos = this->mapToScene(QPoint(curPoint.x(), curPoint.y()));
-
- qreal viewWidth = viewport()->width();
- qreal viewHeight = viewport()->height();
-
- qreal hScale = curPoint.x() / viewWidth;
- qreal vScale = curPoint.y() / viewHeight;
-
- int wheelDeltaValue = event->delta();
- // 当前放缩倍数;
- qreal scaleFactor = this->matrix().m11();
- if ((scaleFactor < 0.4 && wheelDeltaValue<0)||(scaleFactor>50 &&wheelDeltaValue>0))
- return;
-
- wheelDeltaValue > 0 ? scale(1.2, 1.2) : scale(1.0/1.2, 1.0/1.2);
- // 将scene坐标转换为放大缩小后的坐标;
- QPointF viewPoint = this->matrix().map(scenePos);
- this->horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale ));
- this->verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale ));
-
- update();
- }
这段代码其实是通过控制ScrollBar来达到目的,但是其实可以不需要这么做,只需要在构造函数中设置属性即可,构造函数如下:
- MyGraphicsView::MyGraphicsView(QWidget *parent)
- : QGraphicsView(parent)
- {
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // 去掉滚动条
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
- setRenderHints(QPainter::Antialiasing);
-
- /*以鼠标中心进行缩放*/
- setMouseTracking(true);
- setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
- setResizeAnchor(QGraphicsView::AnchorUnderMouse);
- /********************/
-
- }
构造函数中的后三句才是重点。之所以还留着滚轮事件中ScrollBar->setValue()是发现在放大过程中放大到一定程度,加载进去的图片就“消失”。
注:在Scene中要设置SceneRect的大小,尽量大,具体看后面附带的代码下载链接;
二、绘制不随窗口变化大小的背景
Demo带有棋盘格的背景,实现是重写View的drawBackground(QPainter * painter, const QRectF & rect);
- void MyGraphicsView::drawBackground(QPainter * painter, const QRectF & rect)
- {
- //绘制背景
- int wid = this->geometry().width();
- int hei = this->geometry().height();
- m_ptCenter = this->mapToScene(wid / 2, hei / 2);
- QPixmap pix(wid, hei);
- QPainter pter(&pix);
- QColor clr_white(Qt::white);
- QColor clr_gray(240, 240, 240, 240);
- int spacing = 15;
- QColor useColor;
- for (int i = 0; i <= floor(wid / spacing); i++)
- {
- for (int j = 0; j <= floor(hei/ spacing); j++)
- {
- useColor = ((i + j) % 2 == 0 ? clr_white : clr_gray);
- pter.fillRect(i*spacing, j*spacing, spacing, spacing, useColor);
- }
- }
- painter->drawImage(rect, pix.toImage());
- }
三、加载自定义图像Item
自定义图像item其实就是继承QGraphicsItem,由于代码里加了很多图形item,只显示部分;
- QRectF MyGraphicsImageItem::boundingRect() const
- {
- return QRectF(-m_Pixmap.width() / 2, -m_Pixmap.height() / 2, m_Pixmap.width(), m_Pixmap.height());
- }
-
- void MyGraphicsImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
- {
- Q_UNUSED(option);
- Q_UNUSED(widget);
- QPen pen = painter->pen();
- pen.setWidth(0);
- pen.setStyle(Qt::SolidLine);
- pen.setColor(QColor(0, 255, 255, 100));
- painter->setPen(pen);
- painter->setBrush(QColor(0, 0, 255, 100));
- painter->drawPixmap(-m_Pixmap.width() / 2, -m_Pixmap.height() / 2, m_Pixmap);
- }
四、在图像Item上绘制图形item
1、图形边缘控制点
边缘控制点其实也是自定义的Item,定义为MyCornerItem,该Item不随视图的缩放而缩放,需要更新移动后item的位置:
- #pragma once
- #ifndef MY_CORNER_ITEM_H
- #define MY_CORNER_ITEM_H
-
- #include <QAbstractGraphicsShapeItem>
- #include <QGraphicsSceneHoverEvent>
- #include <QPainter>
- #include <QCursor>
- #include <QGraphicsItem>
-
- enum CustomType {
- TypeImage = 65536 + 1,
- TypeCorner = 65536 + 2,
- TypeRect,
- TypeRotateRect,
- TypeCircle
- };
-
- constexpr int CORNER_SIZE = 3;
-
- enum SelectionHandleState
- {
- SelectionHandleOff,
- SelectionHandleInactive,
- SelectionHandleActive
- };
-
- enum CornerDirction //鼠标经过时的形状
- {
- None = 0,
- LeftTop,
- Top,
- RightTop,
- Right,
- RightBottom,
- Bottom,
- LeftBottom,
- Left,
- Rotation, //旋转
- };
-
- class MyCornerItem : public QAbstractGraphicsShapeItem
- {
- /*Q_OBJECT*/
-
- public:
- explicit MyCornerItem(QGraphicsItem *parent, QPointF point, CornerDirction dir, bool control = false);
- virtual ~MyCornerItem() {};
- bool hitTest(const QPointF &point);
- CornerDirction getDir() const { return m_Dir; }
- void setState(SelectionHandleState state);
- void move(QPointF point);
- void cornerTranslate(QPointF point);
- inline void setSelectState(bool bState) { m_bSelect = bState; }
- inline bool getSelectState() { return m_bSelect; }
- inline QPointF getPointCenter() { return m_point; }
-
- virtual int type() const { return TypeCorner; }
-
- private:
- QBrush m_brush;
- QPointF m_point;
- CornerDirction m_Dir;
- SelectionHandleState m_State;
- QCursor m_RotateCursor; //旋转图标
- double m_scaleFactor;
- bool m_bSelect; //对由多个点组成的图形,点击被选中的标志
- QPointF m_ptPress, m_ptMove;
-
- protected:
- virtual QRectF boundingRect() const override;
- virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
- virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE;
- virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
-
-
- };
-
- #endif
- #include "MyCornerItem.h"
- #include <QDebug>
-
- MyCornerItem::MyCornerItem(QGraphicsItem * parent, QPointF point, CornerDirction dir, bool control)
- :QAbstractGraphicsShapeItem(parent)
- , m_point(point)
- ,m_Dir(dir)
- {
- setAcceptHoverEvents(true);
- QPixmap pixRotate = QPixmap("Resources\\icon\\rotate.png");
- m_RotateCursor = QCursor(pixRotate);
- m_scaleFactor = 1;
- m_bSelect = false;
- m_brush = QBrush(Qt::white);
- }
-
- void MyCornerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
- {
- Q_UNUSED(option); //这个宏是用来把不用到的参数注掉的功能
- Q_UNUSED(widget);
- m_scaleFactor = painter->matrix().m11();
- painter->save();
- QPen pen;
- pen.setWidth(0);
- pen.setStyle(Qt::SolidLine);
- painter->setPen(pen);
- painter->setBrush(m_brush);
- painter->setRenderHint(QPainter::Antialiasing, false); //不开反走样
- painter->drawEllipse(m_point, CORNER_SIZE/ m_scaleFactor, CORNER_SIZE/ m_scaleFactor);
- painter->restore();
- }
-
- bool MyCornerItem::hitTest(const QPointF & point)
- {
- //QPointF pt = mapFromScene(point);
- return boundingRect().contains(point);
- }
-
- void MyCornerItem::setState(SelectionHandleState state)
- {
- if (state == m_State)
- return;
- switch (state) {
- case SelectionHandleOff:
- hide();
- break;
- case SelectionHandleInactive:
- case SelectionHandleActive:
- show();
- break;
- }
- m_State = state;
- }
-
- void MyCornerItem::move(QPointF point)
- {
- if (point == m_point)
- return;
- //moveBy(0, 0);
- m_point = point;
- update();
- }
-
- void MyCornerItem::cornerTranslate(QPointF point)
- {
- QPointF local = point + boundingRect().topLeft();
- QRectF delta = QRectF(local, boundingRect().size());
- prepareGeometryChange();
- m_point = delta.center();
- update();
- }
-
- QRectF MyCornerItem::boundingRect() const
- {
- double centerX = m_point.x() - CORNER_SIZE * 2 / m_scaleFactor / 2;
- double centerY = m_point.y() - CORNER_SIZE * 2 / m_scaleFactor / 2;
- return QRectF(centerX, centerY, CORNER_SIZE * 2 / m_scaleFactor, CORNER_SIZE * 2 / m_scaleFactor);
- }
-
- void MyCornerItem::mousePressEvent(QGraphicsSceneMouseEvent * event)
- {
- if (event->button() == Qt::LeftButton)
- {
- m_ptPress = event->scenePos();
- m_ptMove = event->scenePos();
- m_bSelect = true;
- }
- }
-
- void MyCornerItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
- {
- if (event->buttons()&Qt::LeftButton)
- {
- m_ptMove = event->scenePos();
- QPointF pt = mapFromScene(m_ptMove) - mapFromScene(m_ptPress);
- m_ptPress = event->scenePos();
- cornerTranslate(pt);
- }
- QGraphicsItem::mouseMoveEvent(event);
-
- }
-
- void MyCornerItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
- {
- /*if (event->button() == Qt::LeftButton)
- {
- m_ptMove = event->scenePos();
- QPointF pt = mapFromScene(m_ptMove) - mapFromScene(m_ptPress);
- m_ptPress = event->scenePos();
- cornerTranslate(pt);
- }
- QGraphicsItem::mouseReleaseEvent(event);*/
- }
-
- void MyCornerItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
- {
- switch (m_Dir)
- {
- case LeftTop:
- case RightBottom:
- setCursor(Qt::SizeFDiagCursor);
- break;
- case LeftBottom:
- case RightTop:
- setCursor(Qt::SizeBDiagCursor);
- break;
- case Top:
- case Bottom:
- setCursor(Qt::SizeVerCursor);
- break;
- case Left:
- case Right:
- setCursor(Qt::SizeHorCursor);
- break;
- case Rotation:
- setCursor(m_RotateCursor);
- break;
- default:
- setCursor(Qt::ArrowCursor);
- break;
- }
- m_brush = QBrush(Qt::green);
- update();
- QGraphicsItem::hoverEnterEvent(event);
- }
-
- void MyCornerItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
- {
- m_bSelect = false;
- m_brush = QBrush(Qt::white);
- update();
- QGraphicsItem::hoverLeaveEvent(event);
- }
-
2、图形基类及工厂
图形基类继承QGraphicsItem,以组合的方式声明边缘点QList<MyCornerItem*> m_HandlesList,主要实现item移动,左键双击改变z值,右双击可以改变颜色
- #ifndef MY_CUSTOMDRAWITEM_H
- #define MY_CUSTOMDRAWITEM_H
-
- #include <QGraphicsItem>
- #include "MyCornerItem.h"
- #include <QPainterPath>
- #include <QColorDialog>
- #include <QDebug>
-
- /* 需要使用的定义及相关函数 */
- constexpr double PI = 3.1415926;
-
- template <typename T> //T 为QPointF 或QPoint
- double Distance(T p1, T p2)
- {
- return std::sqrt(std::pow(p1.x() - p2.x(), 2) + std::pow(p1.y() - p2.y(), 2));
- }
-
-
- class QGraphicsItem;
- /**图形基类**/
- class CustomItemBase : public QGraphicsItem
- {
- public:
- CustomItemBase(QGraphicsItem *parent = nullptr)
- {
- setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges);
- this->setAcceptHoverEvents(true);
- m_bUseDoubleClick = true;
- m_brush = QBrush(QColor(0, 0, 255, 100));
- }
- virtual ~CustomItemBase() {};
-
- void SetState(SelectionHandleState state);
- bool isCornerSelected(int &index);
-
- void itemAtImage2Move(QPointF point)
- {
- move(point);
- }
-
- virtual int type() const = 0;
- virtual void move(QPointF point) = 0; //平移
- virtual void updateShape() = 0; //拖动corner后要更新形状
- virtual void updateConnerPos() = 0; //移动后更新所有corner的位置
- virtual QPainterPath shape() const = 0;
- protected:
- virtual QRectF boundingRect() const = 0;
- virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) = 0;
- virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
- virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
- virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
- virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
-
- public:
- QRectF m_rect; //外接矩形
- QList<MyCornerItem*> m_HandlesList;
- QPointF m_ptPress,m_ptMove;
- QBrush m_brush;
- bool m_bUseDoubleClick;
- };
-
- class CustomItemBaseFactory
- {
- public:
- virtual ~CustomItemBaseFactory() {}
- virtual CustomItemBase* CreateCustomItem(QVector<QPointF> vecPoint) = 0;
- virtual void DrawOnPaint(QPainter* painter, QVector<QPointF> vecPoint) = 0;
- virtual int NeedClickCount()
- { return --m_nClickCnt; } //图形需要几步完成
-
- int m_nClickCnt;
- inline int GetNeedCnt() { return m_nNeedCnt; }
-
- protected:
- int m_nNeedCnt; //不变
- };
- #include "MyCustomDrawItem.h"
- #include <QGraphicsScene>
- #include <QDebug>
-
- /************************************************************************/
- /* 图形基类相关函数 */
- /* 左双击改变Z值,右双击改变颜色 */
- /************************************************************************/
- void CustomItemBase::SetState(SelectionHandleState state)
- {
- for (auto item: m_HandlesList)
- item->setState(state);
- }
-
- bool CustomItemBase::isCornerSelected(int & index)
- {
- bool bSelect = false;
- index = 0;
- for (auto item : m_HandlesList)
- {
- if (item->getSelectState())
- {
- bSelect = true;
- break;
- }
- index++;
- }
- return bSelect;
- }
-
- QVariant CustomItemBase::itemChange(GraphicsItemChange change, const QVariant & value)
- {
- if (change == QGraphicsItem::ItemSelectedHasChanged)
- {
- qDebug() << "Item Selected:" << value.toString();
- SetState(value.toBool() ? SelectionHandleActive : SelectionHandleOff);
- }
- else if (change == QGraphicsItem::ItemRotationHasChanged)
- {
- qDebug() << "Item Rotation Changed:" << value.toString();
- }
- else if (change == QGraphicsItem::ItemTransformOriginPointHasChanged)
- {
- qDebug() << "ItemTransformOriginPointHasChanged:" << value.toPointF();
- }
- return QGraphicsItem::itemChange(change, value);
- }
-
- void CustomItemBase::mousePressEvent(QGraphicsSceneMouseEvent * event)
- {
- if (event->button() == Qt::LeftButton)
- {
- m_ptPress = event->scenePos();
- m_ptMove = event->scenePos();
- for (auto corner:m_HandlesList)
- {
- corner->setZValue(this->zValue());
- }
- }
- QGraphicsItem::mousePressEvent(event);
- }
-
- void CustomItemBase::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
- {
- if (event->buttons() & Qt::LeftButton)
- {
- int index = 0;
- if (!isCornerSelected(index))
- {
- m_ptMove = event->scenePos();
- QPointF pt = mapFromScene(m_ptMove) - mapFromScene(m_ptPress);
- m_ptPress = event->scenePos();
- move(pt);
- }
- update();
- }
- }
-
- void CustomItemBase::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
- {
- if (event->button() == Qt::LeftButton)
- {
- for (auto item : m_HandlesList)
- {
- item->setSelectState(false);
- }
- QGraphicsItem::mouseReleaseEvent(event);
- }
- }
-
- void CustomItemBase::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
- {
- if (event->button() == Qt::RightButton)
- {
- if (m_bUseDoubleClick)
- {
- QColorDialog dlg;
- if (dlg.exec() == QDialog::Accepted)
- {
- QColor color = dlg.selectedColor();
- color.setAlpha(100);
- m_brush = QBrush(color);
- }
- }
- }
- }
至于为什么还要加个“工厂”,主要就是要加入一个图形,如果以switch的方式分别new出相关的类,这样不便于后续添加其他图形,使用工厂模式就解决了该问题。图形有自己的工厂,使用的时候只要传入相应的工厂指针就好了【不知道该模式的话自行补】。下面仅展示正矩形和圆的实现:
- /**************矩形******************/
- class CustomRectItem :public CustomItemBase
- {
- public:
- CustomRectItem(QRectF &rect, QGraphicsItem *parent = nullptr);
-
- virtual int type() const { return TypeRect; }
-
- virtual void move(QPointF point);
- virtual void updateShape(); //一个corner改变则进行一次更新
- virtual void updateConnerPos();
- virtual QPainterPath shape() const;
-
- protected:
- virtual QRectF boundingRect() const;
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- };
-
- class CustomRectItemFactory : public CustomItemBaseFactory
- {
- public:
- CustomRectItemFactory()
- {
- m_nClickCnt = 1;
- m_nNeedCnt = 1;
- }
- virtual CustomItemBase* CreateCustomItem(QVector<QPointF> vecPoint)
- {
- return new CustomRectItem(QRectF(vecPoint.at(0), vecPoint.at(1)));
- }
- virtual void DrawOnPaint(QPainter* painter, QVector<QPointF> vecPoint)
- {
- painter->drawRect(QRectF(vecPoint.at(0), vecPoint.at(1)));
- }
- };
-
- /**************圆**************/
- class CustomCircleItem :public CustomItemBase
- {
- public:
- CustomCircleItem(QPointF center, double radius, QGraphicsItem *parent = nullptr);
-
- virtual int type() const { return TypeCircle; }
-
- virtual void move(QPointF point); //平移
- virtual void updateShape();
- virtual void updateConnerPos(); //移动后更新所有corner的位置
- virtual QPainterPath shape() const;
-
- protected:
- virtual QRectF boundingRect() const;
- virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
- };
-
- class CustomCircleItemFactory : public CustomItemBaseFactory
- {
- public:
- CustomCircleItemFactory()
- {
- m_nClickCnt = 1;
- m_nNeedCnt = 1;
- }
- virtual CustomItemBase* CreateCustomItem(QVector<QPointF> vecPoint)
- {
- double dRadius = Distance(vecPoint.at(0), vecPoint.at(1));
- return new CustomCircleItem(vecPoint.at(0), dRadius);
- }
- virtual void DrawOnPaint(QPainter* painter, QVector<QPointF> vecPoint)
- {
- double radius = Distance(vecPoint.at(0), vecPoint.at(1));
- painter->drawEllipse(vecPoint.at(0), radius, radius);
- }
- };
- /************************************************************************/
- /* 图形子类函数实现 */
- /* 1、 正矩形 */
- /************************************************************************/
- CustomRectItem::CustomRectItem(QRectF & rect, QGraphicsItem * parent)
- {
- m_rect = rect;
- m_HandlesList.clear();
- const int num = 8;
- QPointF point[num] = { QPointF((rect.left() + rect.right()) / 2,rect.bottom()),QPointF(rect.left(),rect.bottom()),
- QPointF(rect.left(),(rect.top() + rect.bottom()) / 2) ,QPointF(rect.left(),rect.top()),
- QPointF((rect.left() + rect.right()) / 2,rect.top()),QPointF(rect.right(),rect.top()),
- QPointF(rect.right(),(rect.top() + rect.bottom()) / 2),QPointF(rect.right(),rect.bottom())};
- CornerDirction dir[num] = { Bottom,LeftBottom ,Left,LeftTop ,Top , RightTop, Right,RightBottom };
- for (int i = 0; i < num; i++)
- {
- MyCornerItem* corner = new MyCornerItem(this, point[i], dir[i]);
- m_HandlesList.push_back(corner);
- }
- }
-
- void CustomRectItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
- {
- Q_UNUSED(option);
- Q_UNUSED(widget);
- QPen pen = painter->pen();
- pen.setWidth(0);
- pen.setColor(QColor(0, 255, 255, 100));
- painter->setPen(pen);
- painter->setBrush(m_brush);
-
- updateShape();
- painter->drawRect(m_rect);
- }
-
- void CustomRectItem::updateShape()
- {
- int index = 0;
- if (isCornerSelected(index))
- {
- QRectF rect = m_rect;
- CornerDirction dir = m_HandlesList[index]->getDir();
- switch (dir)
- {
- case Top:
- rect.setTop(m_HandlesList[index]->getPointCenter().y());
- break;
- case Right:
- rect.setRight(m_HandlesList[index]->getPointCenter().x());
- break;
- case Bottom:
- rect.setBottom(m_HandlesList[index]->getPointCenter().y());
- break;
- case Left:
- rect.setLeft(m_HandlesList[index]->getPointCenter().x());
- break;
- case LeftTop:
- rect.setTopLeft(m_HandlesList[index]->getPointCenter());
- break;
- case LeftBottom:
- rect.setBottomLeft(m_HandlesList[index]->getPointCenter());
- break;
- case RightTop:
- rect.setTopRight(m_HandlesList[index]->getPointCenter());
- break;
- case RightBottom:
- rect.setBottomRight(m_HandlesList[index]->getPointCenter());
- break;
- default:
- break;
- }
- prepareGeometryChange();
- m_rect = rect;
- updateConnerPos();
- }
- }
-
- QPainterPath CustomRectItem::shape() const
- {
- QPainterPath path;
- path.addRect(boundingRect());
- return path;
- }
-
- void CustomRectItem::move(QPointF point)
- {
- QPointF local = point + m_rect.topLeft();
- QRectF delta = QRectF(local, m_rect.size());
- prepareGeometryChange();
- m_rect = delta;
- updateConnerPos();
- }
-
- void CustomRectItem::updateConnerPos()
- {
- const QRectF rect = m_rect;
- for (auto item : m_HandlesList)
- {
- CornerDirction dir = item->getDir();
- switch (dir)
- {
- case Top:
- item->move((rect.topLeft()+rect.topRight())/2);
- break;
- case Right:
- item->move((rect.topRight()+ rect.bottomRight())/2);
- break;
- case Bottom:
- item->move((rect.bottomLeft()+ rect.bottomRight())/2);
- break;
- case Left:
- item->move((rect.topLeft()+ rect.bottomLeft())/2);
- break;
- case LeftTop:
- item->move(rect.topLeft());
- break;
- case LeftBottom:
- item->move(rect.bottomLeft());
- break;
- case RightTop:
- item->move(rect.topRight());
- break;
- case RightBottom:
- item->move(rect.bottomRight());
- break;
- }
- }
- }
-
- QRectF CustomRectItem::boundingRect() const
- {
- return m_rect;
- }
圆形实现也类似,只要理解了正矩形,圆形也一样。
因为所有的图形类都是在图像上画的,所以在图像Item中声明CustomItemBaseFactory* m_itemFactory; 使用的话就简单贴下代码 [具体请看下载链接的代码]:
m_rectFactory = new CustomRectItemFactory;
m_Scene->m_ImageItem->m_itemFactory = m_rectFactory;
总结
因为只是练习的demo,所以在完成正矩形,旋转矩形和圆形这三个图像就不在继续了,这里只是做个Mark,后面想继续在继续完善。
下载链接地址:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。