文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Qt如何实现实时鼠标绘制图形

2023-06-29 02:49

关注

小编给大家分享一下Qt如何实现实时鼠标绘制图形,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

展示效果

Qt如何实现实时鼠标绘制图形

功能实现

想要实现鼠标拖拽绘图的效果,离不开鼠标的三大事件:按下、移动、释放

那么具体实现实时绘制矩形框的核心流程是什么呢?

鼠标左键点击,记录初始点击位置

在窗口中移动鼠标,实时获取鼠标拖动点,根据拖动点绘制指定形状

鼠标点击右键释放鼠标,绘制最终图形

描述的实现流程很简单,那么,接下来就实际操作吧!

在进行鼠标点击绘制的时候,为了兼容多个图形的实时绘制,这里,不只是用两个QPoint成员变量记录鼠标点,而是采取了vector<QPontF>容器存储的方式。

例如:三角形图形,需要三个点才能确定图形;曲线图形,是由N多个点才能确定图形;等等。。。

所以说,这里采用了vector容器进行数据存储,任何图形的点都可以进行存储。

所有的图形枚举类型,如下表格:

枚举类型形状
Drawing_Normal无图形绘制
Drawing_Circular圆形
Drawing_StraightLine直线
Drawing_Rectangular矩形
Drawing_Triangle三角形
Drawing_ManyLineSegements多线段
Drawing_Curve曲线

今天只讲述 矩形:Drawing_Rectangular

1:记录图形第一个绘制点

只有鼠标点击后才能获取当前点击点的位置,所以,记录按下点操作应该是在鼠标的mousePressEvent中实现的。

void QCustomQGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent * e){//TODO:鼠标左键,点击绘制图形;鼠标右键,点击拖动图形QGraphicsScene::mousePressEvent(e);if (e->button() & Qt::LeftButton){                //当图形处于绘制状态时if (m_enumShape!= Drawing_Normal){//记录鼠标按下的点                        m_vetPoints.push_back(e->scenePos());}}}

代码解析:当进入到鼠标按下消息后,只有在左键按下状态时,才做绘图操作,并且当前形状枚举类型有效。

2:实时获取鼠标最新位置并绘图

鼠标想要实时绘制,那一定是在鼠标的mouseMoveEvent事件中操作的。

void QCustomQGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent * e){//TODO:鼠标移动时,如果存在有效图形类型,进行图形绘制QGraphicsScene::mouseMoveEvent(e);if (m_enumShape!= Drawing_Normal){                m_pTempLayer->DrawShape(m_enumShape, m_vetPt, e->scenePos());}}

代码解析:当鼠标进入到mouseMoveEvent事件后,并且,当前枚举类型处于有效状态时,需要实时绘制图形。

函数DrawShape的讲解:

参数1:图形的枚举类型,根据不同枚举,绘制不同的图形

参数2:vector<QPointF>传入已经记录的鼠标点,可以是多个,但最少是1个。就例如当前绘制矩形来说,该容器中只是存储了一个绘制点。

参数3:鼠标在mouseMoveEvent中实时拖动点

DrawShape函数实现代码,如下:

void QTempCanvasLayer::DrawShape(ENUM_DrawingGraphic enumShape, std::vector<QPointF> vetPt, QPointF ptCurrent){m_pTempCanvasImg->fill(Qt::transparent);m_pTempPainter->setRenderHint(QPainter::Antialiasing, true);m_pTempPainter->setCompositionMode(QPainter::CompositionMode_Source);m_pTempPainter->setPen(QPen(QColor(51, 51, 51), 1, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin));switch (enumShape){case Drawing_Circular: //圆形break;case Drawing_StraightLine: //直线break;case Drawing_Rectangular: //矩形m_pTempPainter->drawRect(QRectF(vetPt[0], ptCurrent));break;case Drawing_Triangle: //三角形break;case Drawing_ManyLineSegements: //多线段break;case Drawing_Curve: //曲线break;default:break;}update();}

代码讲解:switch语句之前的内容都是在设置图形的风格,比如:setRenderHint防止图形走样;最需要我们注意的是下面一句代码:

m_pTempCanvasImg->fill(Qt::transparent);

如果你忘记设置了,当鼠标在拖动绘制图形时,会导致拖拽线条重叠的效果,就如下面展示效果一样,如图所示:

Qt如何实现实时鼠标绘制图形

3:释放绘制点,绘制最终图形

鼠标事件:mouseReleaseEvent

void QCustomQGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * e){//TODO:鼠标释放之后操作QGraphicsScene::mouseReleaseEvent(e);if (m_enumShape == Drawing_Normal){return;}//存在有效的图形类型,进行最终图形绘制if (e->button() & Qt::RightButton){if (m_enumShape == Drawing_Rectangular){//绘制直线,需要存储两个有效点if (m_vetPt.size() == 2){this->DrawRealShape(m_vetPt);                                //如果当前正在绘制图形,直接清除this->ClearCurrentDrawingShape(); }}}}

代码解析:触发了鼠标释放事件后,并且是鼠标右键点击(在这里都是以鼠标右键点击作为最终的图形绘制完成),此时,根据不同的枚举类型进行图形绘制。

对于矩形图形来说,只需要两个有效的点就会完整对图形的绘制,其中this->DrawRealShape中进行最终点的绘制。

一个图形数据绘制成功之后,需要将上一次存储的临时点进行清除,以备后续图形绘制使用,说白了,也就是vector<QPointF>容器需要清除

实现完成了鼠标的三大事件,一个完整的实时鼠标图形绘制思路已经完成了。

看完了这篇文章,相信你对“Qt如何实现实时鼠标绘制图形”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯