Qt实现实时鼠标绘制图形

 更新时间:2022年2月8日 09:48  点击:345 作者:中国好公民st

上一章节介绍了关于QGraphicsView的基础讲解,以及简单的类图创建,由上一章节中最后展示的动画效果来看,今年主要讲述如何在QGraphicsView架构下,实时拖动鼠标绘制图形!

今天主要以矩形为例,再来看一下展示效果吧!

功能实现

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

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

第一步:鼠标左键点击,记录初始点击位置

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

第三步:鼠标点击右键释放鼠标,绘制最终图形

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

在进行鼠标点击绘制的时候,为了兼容多个图形的实时绘制,这里,不只是用两个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);

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

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>容器需要清除

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

总结

实现鼠标实时绘图的功能,无论是MFC框架还是Qt框架,基本原理都是一致的,基本上不会离开鼠标的三大事件。

到此这篇关于Qt实现实时鼠标绘制图形的文章就介绍到这了,更多相关Qt鼠标绘制图形内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://juejin.cn/post/7059340299595677726

[!--infotagslink--]

相关文章

  • 写得不错的jquery table鼠标经过变色代码

    代码如下:$(&#39;#<%=AllEvent.ClientID%> tr:not(:has("th"))&#39;).hover(function () { $bg = $(this).css(&#39;background-color&#39;); $(this).css(&#39;background-...2013-10-03
  • 鼠标划过实现延迟加载并隐藏层的js代码

    鼠标划过实现延迟加载并隐藏层的js代码...2013-10-13
  • PS怎么排除重叠图形

    PS排除重叠形状是什么意思?很多朋友都不是很清楚,其实方法很简单的,下面小编就为大家介绍介绍一下,不会的朋友可以参考本文,来看看吧。 步骤:1、在PS中,选择“矩形工具...2016-12-31
  • C#模拟window操作鼠标的方法

    这篇文章主要介绍了C#模拟window操作鼠标的方法,可实现模拟鼠标移动到固定位置后点击右键的功能,涉及鼠标常用事件的操作技巧,需要的朋友可以参考下...2020-06-25
  • 基于JavaScript获取鼠标位置的各种方法

    这篇文章主要介绍了基于JavaScript获取鼠标位置的各种方法 ,需要的朋友可以参考下...2015-12-18
  • C#获取鼠标在listview右键点击单元格的内容方法

    下面小编就为大家带来一篇C#获取鼠标在listview右键点击单元格的内容方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • Qt 使用Poppler实现pdf阅读器的示例代码

    下面小编就为大家分享一篇Qt 使用Poppler实现pdf阅读器的示例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
  • 将matplotlib绘图嵌入pyqt的方法示例

    这篇文章主要介绍了将matplotlib绘图嵌入pyqt的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-27
  • JS实现网页游戏中滑块响应鼠标点击移动效果

    本文实例讲述了JS实现网页游戏中滑块响应鼠标点击移动效果。分享给大家供大家参考,具体如下:这是网页游戏中的一个有趣效果,可以完成以下几个动作:滚动、scroll 8个方向、鼠标坐标获娶对象上下左右位置获取,大家可以自己添...2015-10-21
  • Photoshop鼠标绘制一颗一星龙珠教程

    今天小编在这里就来给Photoshop的这一款软件的使用者们来说下用鼠标绘制一颗一星龙珠的教程,各位想知道具体绘制方法的使用者们,那么下面就快来跟着小编一起看一看吧。...2016-09-14
  • R语言学习ggplot2绘制统计图形包全面详解

    这篇文章主要为大家详细介绍了R语言学习ggplot2绘制统计图形包的全面知识讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助...2021-11-06
  • vivo x9怎么设置图形解锁?vivo x9设置图形解锁教程

    本篇文章介绍了vivo x9如何设置图形解锁的教程,手机小白们快来看一看吧。 问:vivo x9怎么设置图形解锁? 答:图形解锁在某种程度上会保护我们的隐私,那么怎么设置图形...2017-01-22
  • unity 如何判断鼠标是否在哪个UI上(两种方法)

    这篇文章主要介绍了unity 判断鼠标是否在哪个UI上的两种实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Qt定时器和随机数详解

    在前一篇中我们介绍了键盘和鼠标事件,其实还有一个非常常用的事件,就是定时器事件,如果要对程序实现时间上的控制,那么就要使用到定时器。而随机数也是很常用的一个功能,在我们要想产生一个随机的结果时就要使用到随机数。本文我们就来简单介绍一下定时器和随机数。...2020-04-25
  • C#简单获取全屏中鼠标焦点位置坐标的方法示例

    这篇文章主要介绍了C#简单获取全屏中鼠标焦点位置坐标的方法,涉及C#针对鼠标位置Position属性的简单操作技巧,需要的朋友可以参考下...2020-06-25
  • JS清除文本框内容离开在恢复及鼠标离开文本框时触发js的方法

    多网站的需要填写的文本框在默认状态下都会给出一个默认的提示语言,当鼠标点击此文本框的时候能够将里面的默认文本清除,当删除输入的文本且焦点离开文本框的时候再将默认的文本写入文本框...2016-01-14
  • JS实现鼠标按下拖拽效果

    这篇文章主要为大家详细介绍了JS实现鼠标按下拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-07-24
  • JavaScript鼠标悬停事件用法解析

    这篇文章主要介绍了JavaScript鼠标悬停事件用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-15
  • 一篇文章教你3分钟如何发布Qt程序

    这篇文章主要给大家介绍了关于教你3分钟如何发布Qt程序的相关资料,文中通过实例代码结束的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-08-24
  • html+css+js实现canvas跟随鼠标的小圆特效源码

    这篇文章主要介绍了html+css+js实现canvas跟随鼠标的小圆特效源码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-15