当前位置: 首页 > 热点

世界观点:Qt鼠标拖动绘制基本几何图形

发布时间:2023-03-22 16:14:10 来源:QT教程

概述

用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