一个实时波形图的封装demo(QT)(qcustomplot)

前言:

        封装的一个实时波形图的类,可以直接提升使用。 提供了接口,可以更改颜色,样式,等等

参考:

Qt Plotting Widget QCustomPlot - Introduction

另外参考了一个大神的作品,链接没找到。

项目文件:

123盘  

123盘  实时波形图官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘

CSDN

【免费】一个实时波形图的封装demo(QT)(qcustomplot)资源-CSDN文库

源码

WaveChart文件夹:

1.加入文件qcustomplot.h 和 qcustomplot.cpp:

2.WaveChart.pri文件:

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport

FORMS += \
    $$PWD/waveWidget.ui

HEADERS += \
    $$PWD/qcustomplot.h \
    $$PWD/waveWidget.h

SOURCES += \
    $$PWD/qcustomplot.cpp \
    $$PWD/waveWidget.cpp

3.waveWidget.h文件:

#ifndef WAVEWIDGET_H
#define WAVEWIDGET_H

#include <QWidget>
#include <QVBoxLayout>
#include <vector>
#include <cstring>
#include <numeric>
//#include <QScrollBar>
#include "qcustomplot.h"
using std::vector;
namespace Ui {
class WaveWidget;
}

class WaveWidget : public QWidget
{
    Q_OBJECT

public:
    explicit WaveWidget(QWidget *parent = nullptr);
    ~WaveWidget();

    void init(bool isShowTicks=true, bool isShowTickLables=true, bool isShowGrid=true, bool isShowSubGrid=true, bool isShowAxis2=true, bool isGraphBigAndSmall=true);
    void setTheme(QColor axis, QColor background);
    void setXAxisLable(const char* name, const char* name2 = "");
    void setYAxisLable(const char* name, const char* name2 = "");
    void setPen(Qt::GlobalColor penColor, QCPGraph::LineStyle lineStyle = QCPGraph::lsLine, QColor brushColor = QColor(255,255, 255, 100), bool isShow = true);
    void addNewData(double data);
    void setTitle(const char* name);

    double getMax();
    double getMin();
    double getAverage();

    QCustomPlot*    getTheChartPlot();
    QCPGraph*       getTheGraph();
    vector<double>  &getTheVector();

private:
    Ui::WaveWidget *ui;

    QCustomPlot*    chartPlot = new QCustomPlot(this);      // 图表
    QCPGraph*       graph;                                  // 曲线
    //QScrollBar      horizontalScrollBar;

    vector<double>  graphData;                              // 图表数据,只作记录使用
    int             timeRange = 10;                         // 时间轴范围
    QTime time;
    double          sum = 0.0;

};

#endif // WAVEWIDGET_H

4.waveWidget.cpp文件

#include "waveWidget.h"
#include "ui_waveWidget.h"

WaveWidget::WaveWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::WaveWidget)
{
    ui->setupUi(this);

    // 初始化图表
    graph = chartPlot->addGraph();
    // graph->addData(1,1);
    // graph->addData(2,3);

    // 初始化设置
    // chartPlot->xAxis->setRange(1, 4096);
    // chartPlot->yAxis->setRange(-1, 350); // 假设灰度值的范围为0-255
    // chartPlot->xAxis->setLabel("Pixel");
    // chartPlot->yAxis->setLabel("Gray Value");

    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(ui->title);
    layout->addWidget(chartPlot);
    chartPlot->setSizePolicy(QSizePolicy::Policy(QSizePolicy::Preferred), QSizePolicy::Policy(QSizePolicy::Expanding));
    //layout->addWidget((QWidget)horizontalScrollBar);
    setLayout(layout);

    // init();


}

WaveWidget::~WaveWidget()
{
    delete ui;
}

void WaveWidget::init(bool isShowTicks, bool isShowTickLables, bool isShowGrid, bool isShowSubGrid, bool isShowAxis2, bool isGraphBigAndSmall)
{
    time = QTime::currentTime();
    // 刻度显示
    chartPlot->xAxis->setTicks(isShowTicks);
    chartPlot->yAxis->setTicks(isShowTicks);
    // 刻度值显示
    chartPlot->xAxis->setTickLabels(isShowTickLables);
    chartPlot->yAxis->setTickLabels(isShowTickLables);
    // 网格显示
    chartPlot->xAxis->grid()->setVisible(isShowGrid);
    chartPlot->yAxis->grid()->setVisible(isShowGrid);
    // 子网格显示
    chartPlot->xAxis->grid()->setSubGridVisible(isShowSubGrid);
    chartPlot->yAxis->grid()->setSubGridVisible(isShowSubGrid);
    // 右和上坐标轴、刻度值显示
    chartPlot->xAxis2->setVisible(isShowAxis2);
    chartPlot->yAxis2->setVisible(isShowAxis2);
    chartPlot->yAxis2->setTicks(isShowAxis2);
    chartPlot->yAxis2->setTickLabels(isShowAxis2);
    // make top right axes clones of bottom left axes. Looks prettier:
//    chartPlot->axisRect()->setupFullAxesBox();
    // make left and bottom axes always transfer their ranges to right and top axes:
    if(isShowAxis2){
        connect(chartPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), chartPlot->xAxis2, SLOT(setRange(QCPRange)));
        connect(chartPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), chartPlot->yAxis2, SLOT(setRange(QCPRange)));
    }

    // 暗色主题
    //setPlotTheme(Qt::white, Qt::black);
    // 亮色主题
    setTheme(Qt::black, Qt::white);
    if(isGraphBigAndSmall){
        // 可放大缩小和移动
        chartPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    }

    // x轴以时间形式显示
    QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    timeTicker->setTimeFormat("%h:%m:%s");
    chartPlot->xAxis->setTicker(timeTicker);
    chartPlot->axisRect()->setupFullAxesBox();
    chartPlot->replot();
}

void WaveWidget::setTheme(QColor axis, QColor background)
{
//----------------------------------------------------------------------------------------//
    // 坐标标注颜色
    chartPlot->xAxis->setLabelColor(axis);
    chartPlot->yAxis->setLabelColor(axis);
    // 坐标刻度值颜色
    chartPlot->xAxis->setTickLabelColor(axis);
    chartPlot->yAxis->setTickLabelColor(axis);
    // 坐标基线颜色和宽度
    chartPlot->xAxis->setBasePen(QPen(axis, 1));
    chartPlot->yAxis->setBasePen(QPen(axis, 1));
    // 坐标主刻度颜色和宽度
    chartPlot->xAxis->setTickPen(QPen(axis, 1));
    chartPlot->yAxis->setTickPen(QPen(axis, 1));
    // 坐标子刻度颜色和宽度
    chartPlot->xAxis->setSubTickPen(QPen(axis, 1));
    chartPlot->yAxis->setSubTickPen(QPen(axis, 1));
    // 坐标标注颜色
    chartPlot->xAxis2->setLabelColor(axis);
    chartPlot->yAxis2->setLabelColor(axis);
    // 坐标刻度值颜色
    chartPlot->xAxis2->setTickLabelColor(axis);
    chartPlot->yAxis2->setTickLabelColor(axis);
    // 坐标基线颜色和宽度
    chartPlot->xAxis2->setBasePen(QPen(axis, 1));
    chartPlot->yAxis2->setBasePen(QPen(axis, 1));
    // 坐标主刻度颜色和宽度
    chartPlot->xAxis2->setTickPen(QPen(axis, 1));
    chartPlot->yAxis2->setTickPen(QPen(axis, 1));
    // 坐标子刻度颜色和宽度
    chartPlot->xAxis2->setSubTickPen(QPen(axis, 1));
    chartPlot->yAxis2->setSubTickPen(QPen(axis, 1));
    // 整个画布背景色
    chartPlot->setBackground(background);
    // 绘图区域背景色
    chartPlot->axisRect()->setBackground(background);
    // 刷新绘图
    chartPlot->replot();
}

void WaveWidget::setXAxisLable(const char *name, const char* name2)
{
    chartPlot->xAxis->setLabel(name);
    if(strlen(name2)!=0)
        chartPlot->xAxis2->setLabel(name2);

    chartPlot->replot();
}

void WaveWidget::setYAxisLable(const char *name, const char* name2)
{
    chartPlot->yAxis->setLabel(name);
    if(strlen(name2)!=0)
        chartPlot->yAxis2->setLabel(name2);

    chartPlot->replot();
}

void WaveWidget::setPen(Qt::GlobalColor penColor, QCPGraph::LineStyle lineStyle, QColor brushColor, bool isShow)
{
    graph->setPen(QPen(penColor)); // 设置线条颜色为蓝色
    graph->setLineStyle(lineStyle); // 设置线型为直线
    graph->setVisible(isShow);

    chartPlot->graph()->setBrush(QBrush(brushColor));

    chartPlot->replot();
}

void WaveWidget::addNewData(double data)
{
    // 系统当前时间 = 系统运行初始时间 + 系统运行时间
    static double start = time.hour()*60*60 + time.minute()*60 + time.second() + time.msec()/1000.0;
    double key = start + time.elapsed()/1000.0;

    // 设置时间轴
    chartPlot->xAxis->setRange(key, timeRange, Qt::AlignRight);
    //chartPlot->rescaleAxes();
    // 刷新绘图水平滚动条
    //horizontalScrollBar.setRange(int(start), int(key));  // 刷新滚动条的范围
    //horizontalScrollBar.setPageStep(1);                  // 设置翻页步长为 1s 的宽度
    //horizontalScrollBar.setValue(int(key));              // 调整滑块位置到最右边
    // 更新曲线绘图
    chartPlot->graph()->addData(key, data);
    chartPlot->replot(QCustomPlot::rpQueuedReplot);

    // 存储曲线的当前值
    graphData.push_back(data);
    sum += data;
}

void WaveWidget::setTitle(const char *name)
{
    ui->title->setText(name);
}

double WaveWidget::getMax()
{
    return *std::max_element(graphData.begin(),graphData.end());
}

double WaveWidget::getMin()
{
    return *std::min_element(graphData.begin(),graphData.end());
}

double WaveWidget::getAverage()
{
    return 1.0*sum/(graphData.size());
}

QCustomPlot *WaveWidget::getTheChartPlot()
{
    return   chartPlot;
}

QCPGraph *WaveWidget::getTheGraph()
{
    return  graph;
}

vector<double> &WaveWidget::getTheVector()
{
    return graphData;
}

5.测试demo:

新建测试界面:

提升为刚刚的类:

效果:

测试:

    ui->setupUi(this);

    // 初始化:可以设置参数
    ui->waveWidget->init();

    // 可选设置:
    ui->waveWidget->setXAxisLable("Time");
    ui->waveWidget->setYAxisLable("Value");
    ui->waveWidget->setPen(Qt::blue, QCPGraph::lsLine, QColor( 36,141,218,255));
    ui->waveWidget->setTheme(Qt::red, Qt::white);
    ui->waveWidget->setTitle("Wave Chart Test");

    // 测试加入数据:
    QTimer *timer = new QTimer(this);
    connect(timer,&QTimer::timeout,[=](){
        ui->waveWidget->addNewData((qrand()%1000)/1000.0);
        qDebug()<<"max:"<<ui->waveWidget->getMax()<<"   min:"<<ui->waveWidget->getMin()<<"  average:"<<ui->waveWidget->getAverage();
        if(num%10==0){
            qDebug()<<"size: "<<ui->waveWidget->getTheVector().size();
            ui->waveWidget->getTheVector().clear();
            qDebug()<<"size: "<<ui->waveWidget->getTheVector().size()<<"********";
        }
        if(num>50){
            timer->stop();
        }
        num++;
    });
    timer->start(100);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JS画摆线

最近看到一个很漂亮的曲线&#xff0c;研究了一下。 从圆心画一条线匀速转动&#xff0c;终点再画一条线转动&#xff0c;2条线转速不同&#xff0c;会画出很漂亮的花纹。 一个周期 完整周期 <html> <style> body { background:black; } p { text-align:center; c…

python脚本实现全景站点欧拉角转矩阵

效果 脚本 import numpy as np import math import csv import os from settings import *def euler_to_rotation_matrix(roll, pitch, yaw):# 计算旋转矩阵# Z-Y-X转换顺序Rz

v-rep--websocket接口

websocket是什么 V-REP 中的 Web Socket 是一种用于在 V-REP 和外部应用程序之间进行通信的协议和技术。Web Socket 基于 TCP 连接&#xff0c;可以提供双向、实时的数据传输&#xff0c;适用于互动性或实时交互性应用。 (比如v-rep在云服务器上运行&#xff0c;通过websocke…

Groovy(第五节) Groovy 之集合

Groovy 可以直接在语言内使用集合。在 Groovy 中,不需要导入专门的类,也不需要初始化对象。集合是语言本身的本地成员。Groovy 也使集合(或者列表)的操作变得非常容易,为增加和删除项提供了直观的帮助。 可以将范围当作集合 在前一节学习了如何用 Groovy 的范围将循环变得…

vue - - - - - vue3使用draggable拖拽组件

vue3使用draggable拖拽组件 一、组件安装二、插件使用三、遇到的问题1. missing required prop&#xff1a; “itemKey” 一、组件安装 yarn add vuedraggablenext // or npm i -S vuedraggablenext二、插件使用 <template><draggableitem-key"id"class&q…

【HDFS】Decommision(退役) EC数据节点剩最后几个块卡住的问题

一、背景 近期操作退役EC集群的节点。在退役的过程中,遇到了一些问题。特此总结一下。 本文描述的问题现象是: 每一批次退役10个节点,完全退役成功后开始操作下一批。 但是,中间有一批次有2台节点的Under Replicated Blocks一直是1,不往下降。 处于Decommissioning状态卡…

三款热门超声波清洗机对比测评:希亦、固特、大宇多维度实测!

如果你非常在意物品的健康卫生&#xff0c;并且希望能够摆脱手动清洗一些物品而彻底解放双手&#xff01;在家备一款超声波清洗机还是非常有必要的&#xff01;无论是珠宝、眼镜还是日常小物&#xff0c;都希望能够保持如新的光泽和卫生状态。那么超声波清洗机是最合适不过的&a…

【Leetcode每日一题】二分查找 - 有效的完全平方数(难度⭐)(19)

1. 题目解析 Leetcode链接&#xff1a;367. 有效的完全平方数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 核心在于判断给定的整数是否可以开方成两个整数相乘&#xff0c;可以就返回false&#xff0c;反之返回true。 2. 算法…

es安装中文分词器 IK

1.下载 https://github.com/medcl/elasticsearch-analysis-ik 这个是官方的下载地址&#xff0c;下载跟自己es版本对应的即可 那么需要下载 7.12.0版本的分词器 2.安装 1.在es的 plugins 的文件夹下先创建一个ik目录 bash cd /home/apps/elasticsearch/plugins/ mkdir ik …

Spring Web 过滤器使用常见错误(上)

我们都知道&#xff0c;过滤器是 Servlet 的重要标准之一&#xff0c;其在请求和响应的统一处理、访问日志记录、请求权限审核等方面都有着不可替代的作用。在 Spring 编程中&#xff0c;我们主要就是配合使用ServletComponentScan 和 WebFilter 这两个注解来构建过滤器。 说起…

java 反射机制 (一)

java反射机制&#xff1a; 即通过外部文件配置&#xff0c;不修改文件源码的情况下&#xff0c;来控制程序&#xff0c;也符合设计模式的OCP原则&#xff08;开闭原则&#xff1a;不修改源码&#xff0c;扩容原则&#xff09; Java Reflection 1.反射机制允许程序在执行期间…

阿里云OSS对象存储的使用和实现万能文件上传

文章目录 阿里云OSS对象存储的使用和实现万能文件上传1、开通阿里云OSS对象存储服务&#xff08;新用户可以免费试用三个月&#xff09;1.1、点击免费试用并选择自己想要使用的服务1.2、咱们这里选择使用第一个存储服务&#xff0c;然后点击立即试用 2、创建存储空间&#xff0…

IP源防攻击IPSG(IP Source Guard)

IP源防攻击IPSG&#xff08;IP Source Guard&#xff09;是一种基于二层接口的源IP地址过滤技术&#xff0c;它能够防止恶意主机伪造合法主机的IP地址来仿冒合法主机&#xff0c;还能确保非授权主机不能通过自己指定IP地址的方式来访问网络或攻击网络。 2.1 IPSG基本原理 绑定…

进制转换md5绕过 [安洵杯 2019]easy_web1

打开题目 在查看url的时候得到了一串类似编码的东西&#xff0c;源码那里也是一堆base64&#xff0c;但是转换成图片就是网页上我们看见的那个表情包 ?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 我们可以先试把前面的img那串解码了 解码的时候发现长度不够&#xff0c;那我们…

三、软考-系统架构设计师笔记-计算机系统基础知识

计算机系统概述 计算机系统是指用于数据管理的计算机硬件、软件及网络组成的系统。 它是按人的要求接收和存储信息&#xff0c;自动进行数据处理和计算&#xff0c;并输出结果信息的机器系统。 冯诺依曼体系计算机结构&#xff1a; 1、计算机硬件组成 冯诺依曼计算机结构将…

PDN分析及应用系列二-简单5V电源分配-Altium Designer仿真分析-AD

PDN分析及应用系列二 —— 案例1:简单5V电源分配 预模拟DC网络识别 当最初为PCB设计打开PDN分析仪时,它将尝试根据公共电源网络命名法从设计中识别所有直流电源网络。 正确的DC网络识别对于获得最准确的模拟结果非常重要。 在示例项目中已经识别出主DC网络以简化该过程。 …

Centos7:自动化配置vim | suoders信任列表添加普通用户

Centos7&#xff1a;自动化配置vim | suoders信任列表添加普通用户 vim 配置原理sudoers系统可信任列表中添加普通用户自动化配置vim vim 配置原理 在目录/etc下有一个vimrc文件&#xff0c;该文件是系统中公共的vim配置文件&#xff0c;对所有用户都成立。  而在每个普通用户…

新品发布 | Ftrans CDS 跨域文件交换集中管控系统

1、背景 现如今&#xff0c;随着经济的快速发展&#xff0c;越来越多的企业架构呈现分散的状态&#xff0c;企业在异国、异地设立分支机构&#xff0c;在日常经营中&#xff0c;企业总部和分支机构间存在平行、垂直及互相交叉的管理模式和业务往来需求&#xff0c;因此&#x…

从0到1实现五子棋游戏!!

Hello&#xff0c;好久不见宝子们&#xff0c;今天来给大家更一个五子棋的程序~ 我们今天要讲的内容如下&#xff1a; 文章目录 1.五子棋游戏介绍1.1 游戏玩法介绍&#xff1a; 2.准备工作2.1 具体操作流程 3.游戏程序主函数4.初始化棋盘4.1.定义宏变量4.2 初始化棋盘 5.打印…

微软广告和网络服务CEO承认OpenAI的Sora将加入Copilot,但需要一些时间

事情的起因是一名网友询问 Sora 是否会加入 Copilot&#xff0c;微软广告和网络服务CEO首席执行官——Mikhail Parakhin 回应说&#xff1a;“最终&#xff0c;但这需要时间。”毕竟投了几十个亿美金进去&#xff0c;不亏是金主爸爸。 图为Mikhail Parakhin Sora是OpenAI开发的…