041-第三代软件开发-QCustcomPlot波形标注

news2024/11/17 19:41:03
头图

第三代软件开发-QCustcomPlot波形标注

文章目录

  • 第三代软件开发-QCustcomPlot波形标注
    • 项目介绍
    • QCustcomPlot波形标注
      • 效果
      • 初始化
      • 绘制

关键字: QtQml关键字3关键字4关键字5

项目介绍

欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。

在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。

在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。

无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!

重要说明☝

☀该专栏在第三代软开发更新完将涨价

QCustcomPlot波形标注

效果

先看看效果,如果抓取到波形,就会在对应的曲线上标注出起点,最高点和最低点,如下图所示。

image-20230807225118468

嘿嘿嘿,不管你是之前就看过,还是从上一篇中了解到了第一个波形的检测方法,在哪里面你应该看到部分QCustcomPlot波形标注的内容,今天咱们这个其实原理还是那个原理,试试今天的这个标注的有点多了。

链接在这里:https://dreamlife.blog.csdn.net/article/details/128716820

image-20230807183545114

初始化

下面的代码没有啥技术含量就是把我们需要用到的控件全部都给它初始化了,完了再隐藏了,这样在默认没有抓到波形的情况下,就是没有的,对于用户来说是不知道我们做了啥操作的。

/**
 * @brief XXXX::initWavesCatched 初始化幅值
 */
void XXXX::initWavesCatched()
{
    /// 数据推平抓取到波形信号
    if(m_dataChannel == 1)
    {
        connect(m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData,&Turing_ElectroPhysiologyPullData::signal_wavesCatched,
                this,&XXXX::slot_wavesCatched);
    }
    else if(m_dataChannel == 2)
    {
        connect(m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData,&Turing_ElectroPhysiologyPullData::signal_wavesCatched,
                this,&XXXX::slot_wavesCatched);
    }
    QPen pen;
    pen.setColor("#2DAAE1");
    pen.setWidth(2);
    pen.setStyle(Qt::SolidLine);

    m_labelTime = new QCPItemText(m_qCustomPlot);
    m_labelTime->setLayer("overlay");
    m_labelTime->setClipToAxisRect(false);
    m_labelTime->setPadding(QMargins(5, 5, 5, 5));
    m_labelTime->setFont(QFont("宋体", 16));
    m_labelTime->setColor(QColor("#2DAAE1"));
    m_labelTime->setVisible(false);

    m_lineTime = new QCPItemLine(m_qCustomPlot);
    m_lineTime->setPen(pen);
    m_lineTime->setLayer("overlay");
    m_lineTime->setClipToAxisRect(false);
    m_lineTime->setVisible(false);

    m_lineStart = new QCPItemLine(m_qCustomPlot);
    m_lineStart->setPen(pen);
    m_lineStart->setLayer("overlay");
    m_lineStart->setClipToAxisRect(false);
    m_lineStart->setVisible(false);

    m_lineMax = new QCPItemLine(m_qCustomPlot);
    m_lineMax->setPen(pen);
    m_lineMax->setLayer("overlay");
    m_lineMax->setClipToAxisRect(false);
    m_lineMax->setVisible(false);

    m_lineMin = new QCPItemLine(m_qCustomPlot);
    m_lineMin->setPen(pen);
    m_lineMin->setLayer("overlay");
    m_lineMin->setClipToAxisRect(false);
    m_lineMin->setVisible(false);


    m_labelAmplitude = new QCPItemText(m_qCustomPlot);
    m_labelAmplitude->setLayer("overlay");
    m_labelAmplitude->setClipToAxisRect(false);
    m_labelAmplitude->setPadding(QMargins(5, 5, 5, 5));
    m_labelAmplitude->setFont(QFont("宋体", 16));
    m_labelAmplitude->setColor(QColor("#2DAAE1"));
    m_labelAmplitude->setVisible(false);

    m_lineAmplitudeTop = new QCPItemLine(m_qCustomPlot);
    m_lineAmplitudeTop->setPen(pen);
    m_lineAmplitudeTop->setLayer("overlay");
    m_lineAmplitudeTop->setClipToAxisRect(false);
    m_lineAmplitudeTop->setVisible(false);


    m_lineAmplitudeBottom = new QCPItemLine(m_qCustomPlot);
    m_lineAmplitudeBottom->setPen(pen);
    m_lineAmplitudeBottom->setLayer("overlay");
    m_lineAmplitudeBottom->setClipToAxisRect(false);
    m_lineAmplitudeBottom->setVisible(false);

}

绘制

经过上面的初始化,这里我们使用了Qt 的经典之一,信号槽,还记得上篇中组后,如果我们抓到波形就会触发一个信号,那个信号连接的槽就是这个函数,这个函数的作用就是根据上篇中的波形坐标,把对应的线,箭头,数据绘制在上面

/**
 * @brief XXXX::slot_wavesCatched  算法波形画图
 * @param chanelIndex
 * @param startIndex
 * @param crestIndex
 * @param troughIndex
 * @param endIndex
 */
void XXXX::slot_wavesCatched(int chanelIndex, int startIndex, int crestIndex, int troughIndex, int endIndex)
{
//    qDebug() << "slot_wavesCatched 1 " << chanelIndex;
    if(startIndex == crestIndex)
    {
        closeWavesCatched();
        return;
    }

    if(chanelIndex +1 != m_dataChannel)
        return;


    // 分别计算 x、y 单位像素大小
    // 获取 x 轴对象
    // 获取 x 轴范围
    // 获取绘图区域大小
    // 计算单位像素大小
    m_xPixelSize = m_qCustomPlot->xAxis->range().size() / m_qCustomPlot->viewport().width();
    m_yPixelSize = m_qCustomPlot->yAxis->range().size() / m_qCustomPlot->viewport().height();


    m_yStartValue= m_qCustomPlot->graph(0)->data()->at(startIndex)->value;
    m_yCrestValue= m_qCustomPlot->graph(0)->data()->at(crestIndex)->value;
    m_yTroughValue= m_qCustomPlot->graph(0)->data()->at(troughIndex)->value;
//    double yEndValue= m_qCustomPlot->graph(chanelIndex)->data()->at(endIndex)->value;

//    qDebug() << "m_yCrestValue" << m_yCrestValue << "m_yTroughValue" << m_yTroughValue;



    m_yCrestValue= m_qCustomPlot->graph(0)->data()->at(crestIndex)->value;
    m_yTroughValue= m_qCustomPlot->graph(0)->data()->at(troughIndex)->value;


    m_lineStart->setVisible(true);
    m_lineStart->start->setCoords(startIndex,m_yStartValue);
    m_lineStart->end->setCoords(startIndex,m_yStartValue-100*m_yPixelSize);


    if(startIndex-100*m_xPixelSize > 0)
    {
        m_labelTime->setVisible(true);
        setStimDelay((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125);
        m_labelTime->setText(QString::number((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125, 'f', 1) + "ms");
        m_labelTime->position->setCoords(startIndex-100*m_xPixelSize, m_yStartValue-50*m_yPixelSize);


        m_lineTime->setVisible(true);
        m_lineTime->start->setParentAnchor(m_labelTime->right);
        m_lineTime->end->setCoords(startIndex-1,m_yStartValue-50*m_yPixelSize);
        m_lineTime->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
    }
    else
    {
        m_labelTime->setVisible(true);
        setStimDelay((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125);
        m_labelTime->setText(QString::number((startIndex + m_turing_ElectroPhysiology->g_turing_ElectroPhysiologyPullData->g_userProfile->stimMaskDelay())*0.125,'f',1) + "ms");
        m_labelTime->position->setCoords(startIndex+50*m_xPixelSize, m_yStartValue-50*m_yPixelSize);


        m_lineTime->setVisible(true);
        m_lineTime->start->setParentAnchor(m_labelTime->left);
        m_lineTime->end->setCoords(startIndex+1,m_yStartValue-50*m_yPixelSize);
        m_lineTime->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)
    }


    if(crestIndex <troughIndex)
    {
        m_lineMax->setVisible(true);
        m_lineMax->start->setCoords(crestIndex,m_yCrestValue);
        m_lineMax->end->setCoords(endIndex,m_yCrestValue);

        m_lineMin->setVisible(true);
        m_lineMin->start->setCoords(crestIndex,m_yTroughValue);
        m_lineMin->end->setCoords(endIndex,m_yTroughValue);
    }
    else
    {
        m_lineMax->setVisible(true);
        m_lineMax->start->setCoords(troughIndex,m_yCrestValue);
        m_lineMax->end->setCoords(endIndex,m_yCrestValue);

        m_lineMin->setVisible(true);
        m_lineMin->start->setCoords(troughIndex,m_yTroughValue);
        m_lineMin->end->setCoords(endIndex,m_yTroughValue);
    }


    m_labelAmplitude->setVisible(true);
    m_labelAmplitude->setText(QString("%1uV").arg(int(m_yCrestValue - m_yTroughValue)));
    m_labelAmplitude->position->setCoords(troughIndex, (m_yCrestValue + m_yTroughValue)/2);

    m_lineAmplitudeTop->setVisible(true);
    m_lineAmplitudeTop->start->setParentAnchor(m_labelAmplitude->top);
    m_lineAmplitudeTop->end->setCoords(troughIndex,m_yCrestValue-1);
    m_lineAmplitudeTop->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)


    m_lineAmplitudeBottom->setVisible(true);
    m_lineAmplitudeBottom->start->setParentAnchor(m_labelAmplitude->bottom);
    m_lineAmplitudeBottom->end->setCoords(troughIndex,m_yTroughValue+1);
    m_lineAmplitudeBottom->setHead(QCPLineEnding::esSpikeArrow);//设置箭头类型(三角形、菱形、方形等)

    m_qCustomPlot->replot(QCustomPlot::rpQueuedReplot);

}

博客签名2021

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

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

相关文章

C++11线程

C11线程 创建线程 创建线程需要包含头文件<thread>&#xff0c;使用线程类std::thread 构造函数 默认构造函数 thread() noexcept; 默认构造函数&#xff0c;构造一个线程对象&#xff0c;但它不会启动任何实际的线程执行。 任务函数构造函数 template< class Fun…

计算机毕业设计选题推荐-短文写作竞赛微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

物联网的音视频基础设施,谁在提供最优解?

声网在作为RTC服务商的同时&#xff0c;也更在成为赛道的核心布道者和推动者&#xff0c;通过一个个场景的逐步落地&#xff0c;进而推动RTC行业产生更大的想象力。 作者|斗斗 出品|产业家 某海外物流企业的控制室内&#xff0c;工作人员正聚精会神地注视着高清视频画面&a…

深入浅出排序算法之快速排序(重要)⭐⭐⭐⭐⭐

目录 1. 算法介绍⭐⭐⭐⭐⭐ 1.1 图示解析 2. 执行流程和代码实现 2.1 挖坑法⭐⭐⭐⭐ 2.2 Hoare法⭐⭐⭐⭐ 2.3 前后指针法&#xff08;了解即可&#xff09; 2.4 非递归实现快速排序&#xff08;了解即可&#xff09; 4. 性能分析 5. 算法改进 5.1 三数选中法 5.2…

ChatGPT正在测试原生文件分析功能,DALL·E 3能P图啦!

10月29日&#xff0c;有部分用户在社交平台上分享&#xff0c;ChatGPT Plus正在测试原生文件上传、分析功能&#xff0c;可以通过文本问答的方式&#xff0c;对上传的PDF等数据文件进行提问、搜索。 例如&#xff0c;上传一份50页的员工手册PDF文件&#xff0c;然后向ChatGPT提…

基于Qt Designer 操作教程

​本章将简介使用 Qt Creator 里自带的 Qt Designer,使用 Qt Designer 比较方便的构造 UI 界面。特点是方便布局,比较形象。 ## 使用 UI 设计器开发程序 在这小节里我们继续学习如何使用 Qt Designer 开发程序,Qt Designer 是属于 Qt Creator 的一个功能而已,大家不要搞混…

一款针对SpringBootEnv页面进行快速漏洞利用

参考GitHub - 0x727/SpringBootExploit: 项目是根据LandGrey/SpringBootVulExploit清单编写&#xff0c;目的hvv期间快速利用漏洞、降低漏洞利用门槛。 &#x1f4dd; TODO 支持Eureka XStream deserialization RCE支持Fastjson 内存马注入支持更多可以使用JNDI内存马注入反序…

英语——歌曲篇——My Heart Will Go On——我心永恒

My Heart Will Go On [Celine Dion我心永恒] Every night in my dreams I see you,I feel you, That is how I know you go on Far across the distance And spaces between us You have come to show you go on Near,far,wherever you are I believe that the heart does g…

huggingface离线模式及默认保存路径

T5Tokenizer.from_pretrained()函数会在线下载huggingface上的模型&#xff0c;并自动保存在C盘的.cache路径下&#xff1a; C:\Users\xxxxx\.cache\huggingface\hub\models--google--t5-v1_1-base # 这里xxxxx代表自己电脑用户名huggingface离线下载 以google/t5-v1_1-base为…

RabbitMQ入门到实战教程,消息队列实战,改造配置MQ

RabbitMQ入门到实战教程&#xff0c;MQ消息中间件&#xff0c;消息队列实战-CSDN博客 3.7.Topic交换机 3.7.1.说明 Topic类型的Exchange与Direct相比&#xff0c;都是可以根据RoutingKey把消息路由到不同的队列。 只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候…

吊打98%的JAVA同行,这份阿里P8架构师升级手册登上天梯!

前言&#xff1a; 我们都是IT人&#xff0c;所以&#xff0c;我们注定了很像。 前段时间有个朋友去阿里面试&#xff0c;作为一个社招生&#xff0c;太多痛苦了。都知道进大厂最好的时机就是应届生的时候。作为社招生&#xff0c;太难了。 我这位朋友经历了五轮面试最后才上…

【AIFEM案例操作】水泵强度分析

AIFEM是由天洑自主研发的一款通用的智能结构仿真软件&#xff0c;助力用户解决固体结构相关的静力学、动力学、振动、热力学等实际工程问题&#xff0c;软件提供高效的前后处理工具和高精度的有限元求解器&#xff0c;帮助用户快速、深入地评估结构的力学性能&#xff0c;加速产…

reactor (百万并发服务器) -- 1

为了从点滴开始&#xff0c;文章会先从一些基础socket去补充一些经常发生但是没有很深入去思考的细节。然后我们再开始去设计reactor的设计&#xff0c;可以选择跳过起过前面部分。 为了能从0开始去设计&#xff0c;测试&#xff0c;优化...整个过程会分为2-3篇文章输出&#x…

【NI-DAQmx入门】传感器基础知识

1.什么是传感器&#xff1f; 传感器可将真实的现象&#xff08;例如温度或压力&#xff09;转换为可测量的电流和电压&#xff0c;因而对于数据采集应用必不可少。接下来我们将介绍您所需的测量类型及其对应的传感器类型。在开始之前&#xff0c;您还可以先了解一些传感器术语&…

优化python程序执行速度

1、问题背景 最近使用python编写的一个蓝牙应用程序&#xff0c;在使用过程中发现传输大量数据时会产生丢包&#xff0c;导致无法接收到完整的数据包。蓝牙接收程序的代码如下。 #蓝牙数据接收处理线程def bt_recv_thread(self):recv_time time.time()while(self.thread_run)…

BUUCTF 神秘龙卷风 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 神秘龙卷风转转转&#xff0c;科学家用四位数字为它命名&#xff0c;但是发现解密后居然是一串外星人代码&#xff01;&#xff01;好可怕&#xff01; 密文&#xff1a; 下载附件&#xff0c;解压得到一个.rar压缩…

动态蛇形卷积管状结构分割【CVPR 2023】

论文下载地址&#xff1a;Excellent-Paper-For-Daily-Reading/nn-block at main 类别&#xff1a;模块 时间&#xff1a;2023/10/31 摘要 血管和道路等管状结构在各种临床和自然环境中具有极其重要的意义&#xff0c;在这些环境中&#xff0c;精确分割对于下游任务的准确性…

C++ Set

定义 set不同于vector,strin,list这种存储容器&#xff0c;set是一种关联式容器&#xff0c;底层是搜二叉&#xff1b; 功能 set可以确定唯一的值&#xff0c;可以排序去重。 接口 insert() #include <iostream> #include<set> using namespace std;int main…

机泵设备如何通过设备健康管理平台实施预测性维护

机泵设备在工业生产中起着至关重要的作用&#xff0c;但长时间运行和频繁使用容易引发各种故障。为了提高机泵设备的可靠性和效率&#xff0c;预测性维护成为一种重要的管理策略。设备健康管理平台作为一种先进的工具&#xff0c;为机泵设备的预测性维护提供了有力支持。本文将…

第七届山东省黄炎培职业教育创新创业大赛圆满结束

山东省黄炎培职业教育创新创业大赛作为职教领域的一项品牌赛事&#xff0c;自举办以来&#xff0c;参赛院校覆盖面不断扩大&#xff0c;大赛水平和社会影响力不断提高&#xff0c;已成为全省职业教育领域的品牌赛事&#xff0c;是激发创新创业活力的重要抓手和有效载体&#xf…