[Qt 实战小项目] —— C++ Qt 实现鼠标拖动旋转功能

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: Qt实现鼠标拖动旋转。

Qt系列教程总目录

零、开始的开始

这是律盘,看古琴课程时,老师有一个纸质的,可以查找各弦散按音位,觉得挺好用,便做了一个软件。这里只聊聊怎么实现鼠标拖动旋转,可以借鉴到其他项目。

在这里插入图片描述

一、实现思路

1. 旋转角度

一般旋转对象函数的输入都是角度,那么怎么获取这个角度呢?
鼠标拖动,当然是从鼠标的操作中获取。这个动作中,鼠标有三个状态:按下、拖动、释放,按下的点是旋转开始点(pressPoint),鼠标拖动旋转过程中的鼠标坐标点是当前点(currentPoint),释放时是旋转结束点,也是最后一个当前点。所以获取这 pressPoint 和 currentPoint,再加上旋转中心点(corePoint),就可以求得旋转角度。
代码实现如下:

//鼠标拖动旋转的角度
int Disk::setAngle(){
   
   
    QLineF lineBegin(corePoint, pressPoint);
    QLineF lineEnd(corePoint, currentPoint);
    mouseAngle = 360 - lineBegin.angleTo(lineEnd);
    return mouseAngle;
}

为什么是用 360 减去,后面会讲。

2. 旋转方向

对于准确的旋转方向,可以把旋转开始点和旋转结束点看作原点在旋转中心的两个向量,然后通过向量的外积确定旋转方向,具体见 向量乘法与其几何意义 ,我们的目的不是获得精确的旋转方向,而且这样会增加软件后台的计算量,所以不选择这种方法。

使用角度定位法(我自己起的名字),就像时钟一样,是几点就在那个固定的位置,是几度,圆盘也在那个固定的位置。把角度分为过去的(oldAngle)和现在的(currentAngle),还有鼠标拖动旋转的角度(mouseAngle),他们都初始化为 0。

3. 实现旋转

通过角度(currentAngle)获得旋转矩阵,通过旋转矩阵获得旋转后的图片,然后更新图片的显示。代码如下:

QMatrix rotatematrix;
rotatematrix.rotate(currentAngle); //通过角度创建旋转矩阵
QPixmap fitpixmap = pix.transformed(rotatematrix,Qt::SmoothTransformation);//旋转

// 更新背景图
this->setIcon(fitpixmap);
this->setIconSize(QSize(fitpixmap.width(), fitpixmap.height()));

4. 实现流程

对于鼠标的三个状态:按下、拖动、释放(释放后旋转就结束了,所以释放动作并不重要,这里不考虑),鼠标按下时,获取 pressPoint 坐标,同时将当前角度 currentAngle(也就是上一次旋转后的位置角度)赋值给旧的角度 oldAngle,代码如下:

//鼠标按下事件
void Disk::mousePressEvent(QMouseEvent *event){
   
   
    pressPoint = event->pos();
    oldAngle = currentAngle;
}

鼠标拖动时,获取当前点坐标(currentPoint),然后利用 mouseAngle 和 oldAngle 计算 currentAngle。而 currentAngle = oldAngle + mouseAngle,然后再利用 currentAngle 对旋转对象进行定位。
到这里你可能会问,oldAngle + mouseAngle,一个方向是加,另一个方向怎么办?
所以我用了以下的算法:

//鼠标移动事件
void Disk::mouseMoveEvent(QMouseEvent *event){
   
   
    currentPoint = event->pos();
    if(oldAngle > 360){
   
   
        oldAngle = oldAngle % 360;
    }

    currentAngle = oldAngle + setAngle(); //setAngle()返回mouseAngle 

    if(currentAngle > 360){
   
   
        currentAngle = currentAngle % 360;
    }
}

oldAngle 和 currentAngle 都对 360 取余,保证他们小于等于 360,否则会出现跳变。当顺时针转动,currentAngle = oldAngle + mouseAngle 很容易理解,逆时针时本应该是 currentAngle = oldAngle - mouseAngle,这就涉及到 “1. 旋转角度” 中为什么要用 360 减去了。lineBegin.angleTo(lineEnd) 函数测量角度是从 lineBegin 到 lineEnd 沿逆时针方向测量的,示意图如下:

20200404222131583.png

我选择了使顺时针理解容易,且 currentAngle 已初始化为 0 ,所以用 360 减去测量角度。如果鼠标逆时针拖动,比如图中右边的情况,mouseAngle = 307,oldAngle = 77,则 currentAngle = oldAngle + mouseAngle = 384,然后对 360 取余,正好是 24,最后利用这个角度进行旋转,一次操作结束。

二、完整代码

源码下载链接
现在该软件为 2.0 版本,添加了十二律、五音、简谱、西音、工尺对应查找功能,如下:

20200404231025262.png

如果你没有积分或只是想使用这个软件,可以私信联系我,有积分的同学希望可以赞助一下。

相关文章
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
773 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
9月前
|
XML Linux 数据格式
Qt对Word网页的读写功能实现
Qt对Word网页的读写功能实现
488 9
|
文字识别 计算机视觉 开发者
基于QT的OCR和opencv融合框架FastOCRLearn实战
本文介绍了在Qt环境下结合OpenCV库构建OCR识别系统的实战方法,通过FastOCRLearn项目,读者可以学习Tesseract OCR的编译配置和在Windows平台下的实践步骤,文章提供了技术资源链接,帮助开发者理解并实现OCR技术。
985 9
基于QT的OCR和opencv融合框架FastOCRLearn实战
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
1538 168
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
473 5
|
算法 网络协议 数据挖掘
C++是一种功能强大的编程语言,
C++是一种功能强大的编程语言,
429 14
|
XML 数据可视化 C语言
001 Qt_从零开始创建项目
本文是Qt专栏的第一篇,介绍了如何创建一个Qt项目。
587 4
|
存储 文件存储 数据库
【QT项目】QT项目综合练习之简易计数器(QT6+文件存储)
【QT项目】QT项目综合练习之简易计数器(QT6+文件存储)
419 2
WK
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
1161 1
|
计算机视觉
基于QT的opencv插件框架qtCvFrameLearn实战
这篇文章详细介绍了如何基于Qt框架开发一个名为qtCvFrameLearn的OpenCV插件,包括项目配置、插件加载、Qt与OpenCV图像转换,以及通过各个插件学习OpenCV函数的使用,如仿射变换、卡通效果、腐蚀、旋转和锐化等。
446 10

推荐镜像

更多
  • qt