【QCustomPlot】1.4 - 绘制动态曲线、波形图,隐藏曲线graph,鼠标移动拖动、滚轮缩放、点击选中

 

Qt使用QCustomPlot绘制动态曲线。

曲线动态更新,主要分为两种情况:整组刷新的定长曲线动态增长的不定长曲线

而整组刷新的不定长曲线比较特殊,适用环境较少,在此不做讲述。主要对上述两种情况的应用进行讲解。

 

整组刷新的定长曲线 适用于显示当前内容,并不需要对历史数据进行记录的情况。实现较为简单。

动态增长的不定长曲线 多显示为波形图,由于记录着历史数据,所以广泛使用在科研、学术、物联等实时绘图领域。

区分这俩的方法,可以观察更新曲线数据点是如何在代码中实现:如果使用 setData ,多半是 整组刷新的定长曲线;而使用 addData,大多为 动态增长的不定长曲线

 

工程源码已同步至GitHub,欢迎下载学习。使用时记得遵循GPLv3哦。

我的学习例程仓库,GitHub:QCustomPlot 学习例程下载

 

 

动态增长的不定长曲线 - 波形图

由于波形图的应用范围较广,以此为例程。

绘制动态曲线包括两个部分:曲线动态更新,坐标轴动态更新。

例程中,坐标轴的动态更新方式:如果x坐标点小于1000,则显示0~当前;大于1000,显示(当前-1000)~ 当前。

更新绘图,replot,在高填充下太浪费资源。有另一种方式replot(QCustomPlot::rpQueuedReplot),可避免重复绘图。

!更新绘图的最好的方法还是将数据填充、和更新绘图分隔开。将更新绘图单独用定时器更新。例程中数据量较少,没用定时器单独更新,实际工程中建议大家加上。

帧率显示的代码参考这篇文章,感谢:https://blog.csdn.net/yxy244/article/details/100099876

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    // 给widget绘图控件,设置个别名,方便书写
    pPlot1 = ui->widget_1;

    // 状态栏指针
    sBar = statusBar();

    // 初始化图表1
    QPlot_init(pPlot1);
}

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

// 绘图图表初始化
void MainWindow::QPlot_init(QCustomPlot *customPlot)
{

    // 创建定时器,用于定时生成曲线坐标点数据
    QTimer *timer = new QTimer(this);
    timer->start(10);
    connect(timer,SIGNAL(timeout()),this,SLOT(TimeData_Update()));

    // 图表添加两条曲线
    pGraph1_1 = customPlot->addGraph();
    pGraph1_2 = customPlot->addGraph();

    // 设置曲线颜色
    pGraph1_1->setPen(QPen(Qt::red));
    pGraph1_2->setPen(QPen(Qt::black));

    // 设置坐标轴名称
    customPlot->xAxis->setLabel("X");
    customPlot->yAxis->setLabel("Y");

    // 设置y坐标轴显示范围
    customPlot->yAxis->setRange(120,-120);

    // 显示图表的图例
    customPlot->legend->setVisible(true);
    // 添加曲线名称
    pGraph1_1->setName("波形1");
    pGraph1_2->setName("波形2");

    // 设置波形曲线的复选框字体颜色
    ui->checkBox_1->setStyleSheet("QCheckBox{color:rgb(255,0,0)}");//设定前景颜色,就是字体颜色

    // 允许用户用鼠标拖动轴范围,用鼠标滚轮缩放,点击选择图形:
    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
}

// 定时器溢出处理槽函数。用来生成曲线的坐标数据。
void MainWindow::TimeData_Update(void)
{
    // 生成坐标数据
    static float f;
    f += 0.01;
    //qDebug() << sin(f)*100;
    // 将坐标数据,传递给曲线
    Show_Plot(pPlot1, sin(f)*100);
}

// 曲线更新绘图
void MainWindow::Show_Plot(QCustomPlot *customPlot, double num)
{
    static double cnt;

    cnt++;
    // 给曲线添加数据
    pGraph1_1->addData(cnt, num);
    pGraph1_2->addData(cnt, num*-1);

    // 设置x坐标轴显示范围,使其自适应缩放x轴,x轴最大显示1000个点
    customPlot->xAxis->setRange((pGraph1_1->dataCount()>1000)?(pGraph1_1->dataCount()-1000):0, pGraph1_1->dataCount());
    // 更新绘图,这种方式在高填充下太浪费资源。有另一种方式rpQueuedReplot,可避免重复绘图。
    // 最好的方法还是将数据填充、和更新绘图分隔开。将更新绘图单独用定时器更新。例程数据量较少没用单独定时器更新,实际工程中建议大家加上。
    //customPlot->replot();
    customPlot->replot(QCustomPlot::rpQueuedReplot);

    static QTime time(QTime::currentTime());
    double key = time.elapsed()/1000.0; // 开始到现在的时间,单位秒
    计算帧数
    static double lastFpsKey;
    static int frameCount;
    ++frameCount;
    if (key-lastFpsKey > 1) // 每1秒求一次平均值
    {
        //状态栏显示帧数和数据总数
        ui->statusbar->showMessage(
            QString("%1 FPS, Total Data points: %2")
            .arg(frameCount/(key-lastFpsKey), 0, 'f', 0)
            .arg(customPlot->graph(0)->data()->size()+customPlot->graph(1)->data()->size())
            , 0);
        lastFpsKey = key;
        frameCount = 0;
    }

}

 

 

隐藏曲线 graph

隐藏曲线 有两种方法:

1. setPen 设置为透明色的方法。但也会影响图例中的颜色。不建议使用。

2. setVisible 设置可见性属性。不会对图例有任何影响。推荐使用。

/// 隐藏曲线有两种方法:1.设置为透明色,但也会影响图例中的颜色    2.设置可见性属性
// 1.设置为透明色的方法,隐藏曲线,但也会影响图例中的颜色。不建议使用。
void MainWindow::on_checkBox_1_stateChanged(int arg1)
{
    if(arg1){
        // 显示
        pGraph1_1->setPen(QPen(Qt::red));
    }else{
        // 不显示,透明色
        pGraph1_1->setPen(QColor(0,0,0,0));
    }
    pPlot1->replot();
}

// 2.设置可见性属性,隐藏曲线,不会对图例有任何影响。推荐使用。
void MainWindow::on_checkBox_2_stateChanged(int arg1)
{
    if(arg1){
        pGraph1_2->setVisible(true);
    }else{
        pGraph1_2->setVisible(false);//void QCPLayerable::setVisible(bool on)
    }
    pPlot1->replot();
}

鼠标移动拖动、滚轮缩放、点击选中

因为在更新曲线的代码段中,增加了设置x轴范围,所以在此例程中左键拖动只适用于y轴。

以鼠标为中心滚轮缩放,和点击选中曲线 全部支持。手册搜索 iSelectPlottables,可以查找到更多功能。

QCustomPlot 自带 鼠标移动拖动、滚轮缩放、点击选中 等功能,只需要添加一段代码。

// 允许用户用鼠标拖动轴范围,以鼠标为中心滚轮缩放,点击选择图形:
customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
// 设置鼠标滚轮的缩放倍率,如果不设置默认为0.85,大于1反方向缩放
//customPlot->axisRect()->setRangeZoomFactor(0.5);
// 设置鼠标滚轮缩放的轴方向,仅设置垂直轴。垂直轴和水平轴全选使用:Qt::Vertical | Qt::Horizontal
customPlot->axisRect()->setRangeZoom(Qt::Vertical);

 

发现个宝藏专栏,功能蛮实用的,感谢:https://blog.csdn.net/qq_31073871/article/details/90260275

更多 QCustomPlot控件的使用操作,会在本专栏的后续篇章介绍,一起学习进步。

工程源码已同步至GitHub,欢迎下载学习。使用时记得遵循GPLv3哦。

我的学习例程仓库,GitHub:QCustomPlot 学习例程下载

猜你喜欢

转载自blog.csdn.net/Mark_md/article/details/109134145