用Qt鼠标事件实现基本几何图形的绘制,支持直线、矩形、圆形、椭圆。后期可以在此基础上进行扩展。
(资料图片)
效果图
实现
本示例使用QGraphics体系来实现,因为要移动对象,所以生成的图形必须是一个单独的对象,鼠标拖动绘制的过程是在临时层中完成,release后生成一个矢量的图形item并添加到场景中。
关键代码
主场景中有一个父rootItem,在scene中将鼠标或触控事件传到rooitem后动态绘制临时的图形,release事件后生成一个标准的图形对象:
本示例使用QGraphics体系来实现,因为要移动对象,所以生成的图形必须是一个单独的对象,鼠标拖动绘制的过程是在临时层中完成,release后生成一个矢量的图形item并添加到场景中。
关键代码
主场景中有一个父rootItem,在scene中将鼠标或触控事件传到rooitem后动态绘制临时的图形,release事件后生成一个标准的图形对象:
void GsRootItem::drawPress(int id, const QPointF &p){ ShapeInfo info; info.firstPos = p; info.type = getCurType(); m_Objs.insert(id,info);}void GsRootItem::drawMove(int id, const QPointF &lastPoint, const QPointF &curPoint){ if(!m_Objs.contains(id)){ return; } ShapeInfo info = m_Objs.value(id); m_pTempLayer->drawShape(info.type,info.firstPos,curPoint);}void GsRootItem::drawRelease(int id, const QPointF &point){ if(!m_Objs.contains(id)){ return; } ShapeInfo info = m_Objs.value(id); drawRealShape(info.type,info.firstPos,point); m_Objs.remove(id); m_pTempLayer->clear();}...void GsRootItem::drawRealShape(GsShapeType type, QPointF p1, QPointF p2){ //计算图形绘制区域 QRectF rect; rect.setX(qMin(p1.x(),p2.x())); rect.setY(qMin(p1.y(),p2.y())); if(type == Shape_Circle){ rect.setWidth(qAbs(p1.y() - p2.y())); rect.setHeight(qAbs(p1.y() - p2.y())); } else{ rect.setWidth(qAbs(p1.x() - p2.x())); rect.setHeight(qAbs(p1.y() - p2.y())); } rect.adjust(-5,-5,5,5); GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this); item->drawShape(p1,p2);}drawRealShape函数就是用于创建一个独立的几何图形,通过以下的工厂模式来生成
GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this);工厂代码:
GsShapeBaseItem *GsShapeFactory::getShapeItem(GsShapeType type,QRectF rectF, QGraphicsObject *parent){ GsShapeBaseItem * item = nullptr; switch (type) { case Shape_Line: item = new GsShapeLineItem(rectF,parent); break; case Shape_Rectange: item = new GsShapeRectangeItem(rectF,parent); break; case Shape_Circle: item = new GsShapeCircleItem(rectF,parent); break; case Shape_Oval: item = new GsShapeOvalItem(rectF,parent); break; default: break; } item->setZValue(10); return item;}在工厂类中会创建不同的图形对象。每一个图形对象是继承于QGraphicsObject然后重写paint函数去进行绘制,比如说原型:
void GsShapeCircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ painter->setRenderHint(QPainter::Antialiasing); QColor color = Qt::red;//(rand()%255,rand()%255,rand()%255); painter->setBrush(color); if(m_bTap){ painter->setPen(QPen(Qt::yellow,5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin)); } else{ painter->setPen(QPen(color,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin)); } painter->drawEllipse(m_firstPoint.x(),m_firstPoint.y(), qAbs(m_lastPoint.y() - m_firstPoint.y()), qAbs(m_lastPoint.y() - m_firstPoint.y()));}其他图形类似。
实现图形的选择和拖动,需要在item中添加以下两句:
setFlag(ItemIsSelectable,true);setFlag(ItemIsMovable,true);然后就可以自由拖动啦。
基本逻辑都很简单。
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
Copyright 2015-2022 西南质量网 版权所有 备案号:皖ICP备2022009963号-8 联系邮箱:39 60 29 14 2@qq.com