QT实现曲线图缩放、拖拽以及框选放大

.h文件

protected:    void saveAxisRange();void wheelEvent(QWheelEvent *event) override;void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;private:QPoint m_lastPoint;bool m_isPress = false;  //这里我把平移的判定初始化成了false,解决鼠标一移进QchartView就跟随移动的情况bool m_ctrlPress;bool m_alreadySaveRange;double m_xMin, m_xMax, m_yMin, m_yMax;QGraphicsSimpleTextItem* m_coordItem;// 框选bool m_isSelecting = false;        // 是否正在框选QPoint m_selectionStart;           // 框选起点QGraphicsRectItem* m_selectionRect = nullptr; // 选框图形项

.cpp文件

void saveAxisRange()
{QValueAxis *axisX = dynamic_cast<QValueAxis*>(this->chart()->axisX());m_xMin = axisX->min();m_xMax = axisX->max();QValueAxis *axisY = dynamic_cast<QValueAxis*>(this->chart()->axisY());m_yMin = axisY->min();m_yMax = axisY->max();
}void wheelEvent(QWheelEvent *event)
{获取当前轴的缩放因子(0.9为缩小,1.1为放大)//const double zoomFactor = 0.9;//const double minRange = 0.01; // 防止缩放到负数或过小获取当前轴范围//QValueAxis* axisX = qobject_cast<QValueAxis*>(chart()->axes(Qt::Horizontal).first());//QValueAxis* axisY = qobject_cast<QValueAxis*>(chart()->axes(Qt::Vertical).first());//if(!axisX || !axisY)//{//    return;//}计算缩放方向(向上滚为缩小,向下滚为放大)//double delta = event->angleDelta().y() > 0 ? zoomFactor : 1.0 / zoomFactor;根据修饰键选择缩放轴//if(event->modifiers() & Qt::ControlModifier)//{//    // 缩放Y轴//    double newMinY = axisY->min() * delta;//    double newMaxY = axisY->max() * delta;//    if(newMaxY - newMinY > minRange)//    {//        axisY->setRange(newMinY, newMaxY);//    }//}//else//{//    // 缩放X轴//    double newMinX = axisX->min() * delta;//    double newMaxX = axisX->max() * delta;//    if(newMaxX - newMinX > minRange)//    {//        axisX->setRange(newMinX, newMaxX);//    }//}//event->accept();const QPoint curPos = event->pos();QPointF curVal = this->chart()->mapToValue(QPointF(curPos));if(!m_alreadySaveRange){this->saveAxisRange();m_alreadySaveRange = true;}const double factor = 1.5;//缩放比例if(event->modifiers() & Qt::ControlModifier){//Y轴QValueAxis *axisY = dynamic_cast<QValueAxis*>(this->chart()->axisY());const double yMin = axisY->min();const double yMax = axisY->max();const double yCentral = curVal.y();double bottomOffset;double topOffset;if(event->delta() > 0){//放大bottomOffset = 1.0 / factor * (yCentral - yMin);topOffset = 1.0 / factor * (yMax - yCentral);}else{//缩小bottomOffset = 1.0 * factor * (yCentral - yMin);topOffset = 1.0 * factor * (yMax - yCentral);}this->chart()->axisY()->setRange(yCentral - bottomOffset, yCentral + topOffset);}else{//X轴QValueAxis *axisX = dynamic_cast<QValueAxis*>(this->chart()->axisX());const double xMin = axisX->min();const double xMax = axisX->max();const double xCentral = curVal.x();double leftOffset;double rightOffset;if(event->delta() > 0){//放大leftOffset = 1.0 / factor * (xCentral - xMin);rightOffset = 1.0 / factor * (xMax - xCentral);}else{//缩小leftOffset = 1.0 * factor * (xCentral - xMin);rightOffset = 1.0 * factor * (xMax - xCentral);}this->chart()->axisX()->setRange(xCentral - leftOffset, xCentral + rightOffset);}
}void mousePressEvent(QMouseEvent *event)
{//if(event->button() == Qt::LeftButton)//{//    m_lastPoint = event->pos();//    m_isPress = true;//}if(event->button() == Qt::LeftButton){// 检测 Ctrl 键是否按下if(QApplication::keyboardModifiers() & Qt::ControlModifier){// 开始框选m_isSelecting = true;m_selectionStart = event->pos();// 创建选框图形项if(!m_selectionRect){m_selectionRect = new QGraphicsRectItem();m_selectionRect->setPen(QPen(Qt::blue, 1, Qt::DashLine));m_selectionRect->setBrush(QColor(100, 100, 255, 50));chart()->scene()->addItem(m_selectionRect);}}else{// 正常平移模式m_lastPoint = event->pos();m_isPress = true;}}
}void mouseMoveEvent(QMouseEvent *event)
{/*if(!m_coordItem){m_coordItem = new QGraphicsSimpleTextItem(this->chart());m_coordItem->setZValue(5);m_coordItem->setPos(100, 60);m_coordItem->show();}const QPoint curPos = event->pos();if(m_isPress){QPoint offset = curPos - m_lastPoint;m_lastPoint = curPos;if(!m_alreadySaveRange){this->saveAxisRange();m_alreadySaveRange = true;}this->chart()->scroll(-offset.x(), offset.y());}*/// 更新坐标显示(原功能保留)if(!m_coordItem){m_coordItem = new QGraphicsSimpleTextItem(chart());m_coordItem->setZValue(5);m_coordItem->setPos(100, 60);}// 处理框选逻辑if(m_isSelecting){// 更新选框图形QRectF rect(m_selectionStart, event->pos());m_selectionRect->setRect(rect.normalized());}// 处理平移逻辑else if(m_isPress){QPoint offset = event->pos() - m_lastPoint;m_lastPoint = event->pos();if(!m_alreadySaveRange){saveAxisRange();m_alreadySaveRange = true;}chart()->scroll(-offset.x(), offset.y());}
}void mouseReleaseEvent(QMouseEvent *event)
{//m_isPress = false;//if(event->button() == Qt::RightButton)//{//    if(m_alreadySaveRange)//    {//        this->chart()->axisX()->setRange(m_xMin, m_xMax);//        this->chart()->axisY()->setRange(m_yMin, m_yMax);//    }//}if(event->button() == Qt::LeftButton){if(m_isSelecting){// 应用框选缩放QRectF rect = m_selectionRect->rect();QPointF topLeft = chart()->mapToValue(rect.topLeft());QPointF bottomRight = chart()->mapToValue(rect.bottomRight());chart()->axisX()->setRange(topLeft.x(), bottomRight.x());chart()->axisY()->setRange(bottomRight.y(), topLeft.y()); // Y轴方向反转// 清理选框chart()->scene()->removeItem(m_selectionRect);delete m_selectionRect;m_selectionRect = nullptr;m_isSelecting = false;}else{m_isPress = false;}}// 原右键恢复功能保留else if(event->button() == Qt::RightButton){if(m_alreadySaveRange){chart()->axisX()->setRange(m_xMin, m_xMax);chart()->axisY()->setRange(m_yMin, m_yMax);}}
}

构造函数中添加代码:

    grabGesture(Qt::PinchGesture);                              //这里只grabGesture了PinchGesture

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/79295.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pandas】pandas DataFrame corr

Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每个元素的绝对值DataFrame.all([axis, bool_only, skipna])用于判断 DataFrame 中是否所有元素在指定轴上都为 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判断…

青藏高原七大河流源区径流深、蒸散发数据集(TPRED)

时间分辨率 月空间分辨率 1km - 10km共享方式 开放获取数据大小 83.27 MB数据时间范围 1998-07-01 — 2017-12-31元数据更新时间 2024-07-22 数据集摘要 通过构建耦合积雪、冻土、冰川等冰冻圈水文物理过程的WEB-DHM模型&#xff08;Water and Energy Budget-based Distribute…

window环境下,如何通过USB接口控制打印机

虽然说大多数情况下&#xff0c;我们可以非常便利的通过打印机驱动来控制打印机&#xff0c;但还是有一些特殊情况&#xff0c;导致无法通过打印机驱动来完成我们预想的任务&#xff0c;比如&#xff0c;打印机只是一个系统设备中的一部分&#xff0c;需要协调其它设备一起工作…

CDGP数据治理主观题评分标准与得分策略

1.数据模型题目评分标准 1)准确理解题目中所描述的业务逻辑和需求得[1分] 2)正确使用模型设计方法,使用信息工程、信息建模集成定义、巴克符号、陈氏符号等其中一种得[1分] 3)正确设计实体和属性,题目中涉及的实体数量为25-30个,10个以内得[2分],10-20个得[3分],25个…

工业设计破局密码:3D 可视化技术点燃产业升级引擎

3D可视化是一种将数据、信息或抽象概念以三维图形、模型和动画的形式呈现出来的技术。3D可视化技术通过构建三维数字孪生体&#xff0c;将设计思维转化为可交互的虚拟原型&#xff0c;不仅打破了传统二维设计的空间局限&#xff0c;更在效率、精度与用户体验层面开创了全新维度…

Qt中在子线程中刷新UI的方法

Qt中在子线程中刷新UI的方法 在Qt中UI界面并不是线程安全的&#xff0c;意味着在子线程中不能随意操作UI界面组件&#xff08;比如按钮、标签&#xff09;等&#xff0c;如果强行操作这些组件有可能会导致程序崩溃。那么在Qt中如何在子线程中刷新UI控件呢&#xff1f; 两种方…

为了摸鱼和吃瓜,我开发了一个网站

平时上班真的比较累&#xff0c;摸鱼和吃瓜还要跳转多个平台的话&#xff0c;就累上加累了。 所以做了一个聚合了全网主流平台热搜的网站。 目前市面上确实有很多这种网站了&#xff0c;所以目前最主要有两点和他们不同&#xff1a; 给热搜列表增加了配图&#xff0c;刷的时候…

操作系统学习笔记第2章 (竟成)

第 2 章 进程管理 【考纲内容】 1.进程与线程&#xff1a; (1) 进程 / 线程的基本概念&#xff1b; (2) 进程 / 线程的状态与转换&#xff1b; (3) 线程的实现&#xff1a;内核支持的线程&#xff1b;线程库支持的线程&#xff1b; (4) 进程与线程的组织与控制&#xff1b; (5)…

77.评论日记

房间要经常搞卫生&#xff0c;不然会很多灰&#xff0c;很多头发&#xff0c;很多垃圾。 当然&#xff0c;即使一直搞卫生&#xff0c;在一些看不到的角落也是会慢慢囤积垃圾。 想要把那些角落也打扫干净&#xff0c;没别的办法&#xff0c;只有把那个角落上所有的东西都移开&a…

语音合成之十二 TTS声学编解码器的演进

TTS声学编解码器的演进 1 引言&#xff1a;声码器/声学编解码器在现代TTS中的关键作用2 奠定基石&#xff1a;从早期声码器到神经合成的曙光3. HiFi-GAN: 革新高效高保真波形生成4. 新的疆域&#xff1a;面向富语义TTS的先进声学编解码器5. XCodec2.0: 统一声学与语义信息6.BiC…

大学之大:悉尼科技大学2025.5.10

悉尼科技大学&#xff1a;从技术先驱到全球创新枢纽的百年征程 一、历史沿革&#xff1a;从技工培训到世界百强名校的蜕变 1. 工业革命的技术火种&#xff08;1843-1945&#xff09; 悉尼科技大学的历史可追溯至1843年成立的悉尼机械学院&#xff08;Sydney Mechanics’ Scho…

安装阿里云的yum源并且下载软件(CentOS7版本)

目录 1. 进入root模式: 2. 进入yum.repos.d文件下 3.备份 4. 安装阿里云的yum源 5. 安装dnf 6. 安装epel-release 7. 清除缓存,并新建缓存 8. 安装智能拼音软件包 8.1安装 8.2 进入应用程序 -- 系统工具 -- 设置 8.3重启后就可以打中文啦~ (需要重新启动才能)…

Discriminative and domain invariant subspace alignment for visual tasks

用于视觉任务的判别性和域不变子空间对齐 作者&#xff1a;Samaneh Rezaei&#xff0c;Jafar Tahmoresnezhad 文章于2018年12月4日收到&#xff0c;2019年5月24日被接受&#xff0c;2019年6月3日在线发表于Iran Journal of Computer Science期刊&#xff0c;DOI: 10.1007/s42…

用jsp简单实现C语言标准化测试系统

C语言标准化测试系统 在Web编程技术的学习过程中&#xff0c;我们小组为了深入理解相关技术原理&#xff0c;提升实践能力&#xff0c;开发了一个基于动态Web工程框架的C语言标准化考试系统。现在&#xff0c;就来和大家分享一下我们的项目经历。 一、实验目的剖析 这个项目…

QMK键盘固件自定义指南 - 打造你的专属键盘体验

QMK键盘固件自定义指南 - 打造你的专属键盘体验 &#x1f680; 前言 在机械键盘的世界里&#xff0c;QMK固件让你的键盘不再只是简单的输入设备&#xff0c;而是可以按照你的意愿定制的强大工具。本文将深入浅出地介绍如何自定义QMK键盘的行为&#xff0c;从基础概念到高级应…

5.9培训

文件上传 先找文件上传的地方&#xff0c;打开代理链接BP&#xff0c;它需要一个xls文件 我们创建一个sqzr.xls bp拦截了之后&#xff0c;我们修改请求&#xff0c;把后缀改成php&#xff0c;发送请求 找到我们的静态资源所在的位置 访问http://192.168.1.100:81/static/upload…

【FAQ】HarmonyOS SDK 闭源开放能力 — PDF Kit

1.问题描述&#xff1a; 预览PDF文件&#xff0c;文档上所描述的loadDocument接口&#xff0c;可以返回文件的状态&#xff0c;并无法实现PDF的预览&#xff0c;是否有能预览PDF相关接口&#xff1f; 解决方案&#xff1a; 1、执行loadDocument进行加载PDF文件后&#xff0c…

AutoDL实现端口映射与远程连接AutoDL与Pycharm上传文件到远程服务器(李沐老师的环境)

文章目录 以上配置的作用前提AutoDL实现端口映射远程连接AutoDLPycharm上传文件到远程服务器以上配置的作用 使用AutoDL的实例:因本地没有足够强的算力,所以需要使用AutoDL AutoDL端口映射:当在实例上安装深度学习的环境,但因为实例的linux系统问题,无法图形化显示d2l中的文件…

【Linux系列】跨平台安装与配置 Vim 文本编辑器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

CountDownLatch 并发编程中的同步利器

CountDownLatch 并发编程中的同步利器 文章目录 CountDownLatch 并发编程中的同步利器一、CountDownLatch 基础概念1.1 什么是 CountDownLatch&#xff1f;1.2 CountDownLatch 的核心方法1.3 基本使用示例 二、CountDownLatch 实战应用2.1 应用场景一&#xff1a;并行任务协调2…