概述

用Qt鼠标事件实现基本几何图形的绘制,支持直线、矩形、圆形、椭圆。后期可以在此基础上进行扩展。

效果图

实现

本示例使用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);

然后就可以自由拖动啦。

代码太多, 就不全部列出来了,基本逻辑都很简单。
代码下载地址

github下载

Qt鼠标拖动绘制基本几何图形相关推荐

  1. JavaScript鼠标拖动绘制方框实现选区

    学习编程,与君共勉. 针对JavaScript拖动鼠标绘制方框实现选区的方法,在网上查了很多,但感觉不是写的很繁琐就是感觉很乱,没有一个详细的步骤,这对于我们这些菜鸟来说真的很难理解,所以我写了一份比 ...

  2. Qt——鼠标拖动调整窗口大小

    要求:鼠标移到界面边角时,鼠标样式相应地发生改变. 实现方法一: 重写mouseMoveEvent,如果鼠标没有按下,则根据鼠标在界面上的位置设置鼠标样式,如果鼠标按下,则根据位置判断该怎样调整界面大 ...

  3. python matplotlib.pyplot 如何实时绘制三维动态窗口?(可鼠标拖动角度)

    实时绘制三维图并更新窗口 # -*- coding: utf-8 -*- """ @File : test.py @Time : 2020/5/26 18:09 @Aut ...

  4. Qt 自定义标题栏,最小化、最大化、关闭窗口,双击最大化,鼠标拖动等效果实现

    文章目录 前言 效果 代码 .pro文件 widget.h widget.cpp widget.ui title.h title.cpp title.ui 前言 本次实验内容为Qt自定义标题栏,最小化 ...

  5. 【QT 5 设置自定义标题栏+学习:《QT实现鼠标拖动调整窗口大小》+基础样例】

    [QT 5 设置自定义标题栏+学习:<QT实现鼠标拖动调整窗口大小>+基础样例] 1.说明 2.实验环境 3.实验目的 4.参考文章 5.实验步骤 (1)下载代码,运行没有错误. (2)加 ...

  6. 【Java AWT 图形界面编程】使用鼠标滚轮缩放 Canvas 画布中绘制的背景图像 ( 绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩放 + 以当前鼠标指针位置为缩放中心 示例 )

    文章目录 一.鼠标滚轮缩放的中心点设置为当前鼠标中心点 - 要点分析 1.保存当前鼠标指针指向的位置 2.根据鼠标指针指向的位置以及比例重新计算图片位置 二.绘制超大图像 + 鼠标拖动 + 鼠标滚轮缩 ...

  7. QGraphicsItem图元拖动绘制(二)

    系列文章目录 QGraphicsItem图元的简单使用(一) 文章目录 系列文章目录 前言 一.简单演示 二.实现代码 总结 前言 接上一章,上一章讲解了如何简单使用图元,通过鼠标点击绘制一个固定图元 ...

  8. 从零开始在windows下使用QT根据点绘制图像

    从零开始在windows下使用QT根据点绘制图像(QPainter or halcon) 前言 QT+msvc+SDK+halcon环境搭建 1 添加 .lib库文件路径 2 添加 .h 头文件 3 ...

  9. PyQt5教程(十二)——实现QQ登录界面(六、实现鼠标拖动界面,鼠标事件)

    PyQt5教程(十二)--实现QQ登录界面(五.实现鼠标拖动界面,鼠标事件) 一.实现界面可以随着鼠标进行拖动 1.主要就是对鼠标事件的实现: def mousePressEvent(self, ev ...

最新文章

  1. php 归并排序,详解PHP归并排序的实现
  2. 对 Excel 工作簿中的数字签名和代码签名的说明
  3. 浅谈AJAX基本实现流程
  4. Fiddler本机调试的方法
  5. login窗口for mysql_CTF| SQL注入之login界面
  6. Git命令学习总结(-)
  7. python打开文件报错无效序列_解决Python 写文件报错TypeError的问题
  8. 小小方法,问题锦集。
  9. 昆仑通态触摸屏数据转发上传_说说昆仑通态(MCGS)的数组功能
  10. php 每七天执行代码,十天学会PHP之第七天
  11. Spring Boot qq邮箱验证码注册和登录验证
  12. Word 内容被锁定的两种解决方法
  13. Java曲线之削峰填谷,四种用户侧“削峰填谷”储能技术方案对比:最快8.26年,最多收益71.76万元...
  14. FZU 2219 StarCraft (哈夫曼树)
  15. CSP201609-3炉石传说
  16. 快排的三种优化方式。
  17. 电商项目day16(购物车实现)
  18. COF多孔复合材料3D-KSC-COFs/ZnO-CdS-Co-Fe2O4/COF-PS-GMA/MW-CNTs-TpPa-COF
  19. 解决双屏同时只能一个工作,另一个黑屏问题
  20. VS Code下载,安装,汉化

热门文章

  1. 用Dropout思想做特征选择,保证效果还兼顾了线上性能?
  2. 大有可为的GNN:DeepWalk
  3. 隐私安全的必答题,网易云信如何解?
  4. 资讯|WebRTC M92 更新
  5. ecplise常用快捷键
  6. SAP S/4HANA使用ABAP获得生产订单的状态
  7. Centos6.x Desktop 關閉防護墻及無關服務
  8. elk之elasticsearch(二)
  9. 解决9.png malformed以及libpng warning: iCCP
  10. 使用Cocoapods快速创建自己的podspec,让你的框架支持cocoapods,podspec