前言:

        我正在做MCU+FreeRtos下位机与Linux环境下QT上位机的模拟温湿度发送接收传输+数据曲线实时显示+LED灯控制系统,其中Qt Chart相关类曲线绘制也是第一次学习,通过网上检索+ai学习,笔记中代码都是源项目的代码为例,以此整理一篇学习笔记,帮助有和我一样想学习这些或有困扰的人。

        除了这篇,对于我做好的这个简单的项目我也会发一篇文章详细记录下。


QT Chart 相关类介绍以及基础使用流程

QChart

      这个类用来存放要绘制的曲线、坐标轴等等对象,你可以理解为一个存放的容器。

    //创建图表容器
    m_chart = new QChart();  
    m_chart->setTitle("温湿度实时曲线");
    m_chart->setAnimationOptions(QChart::SeriesAnimations); // 仅曲线有动画 
    m_chart->setAnimationDuration(250); // 调整动画时长

QLineSeries

      显示线条数据,例如折线、曲线等等,可以通过QChart的addSeries()函数来添加,

setName();setColor(Qt::red);可以分别用来设置线条的名字,颜色(红色为例)

    //温度曲线
    m_tempSeries = new QLineSeries();
    m_tempSeries->setName("温度 (°C)");
    m_tempSeries->setColor(Qt::red);
    //湿度曲线
    m_humiSeries = new QLineSeries();
    m_humiSeries->setName("湿度 (%)");
    m_humiSeries->setColor(Qt::blue);
    

    //chart添加函数
    m_chart->addSeries(m_tempSeries);
    m_chart->addSeries(m_humiSeries);

QValueAxis

      这是用来创建坐标轴的类。具体用法:

    //创建x轴
    m_axisX = new QValueAxis();
    m_axisX->setTitleText("数据点");
    m_axisX->setRange(0,MAX_DATA_POINTS);//设置x轴范围 0-50  
    m_axisX->setTickCount(6); // 固定显示6个刻度
    
    //创建y轴
    m_axisY = new QValueAxis();
    m_axisY->setTitleText("数值");
    m_axisY->setRange(0,100); //设置y轴范围 0-100
    m_axisY->setTickCount(6);// 固定显示6个刻度
    
    //将坐标轴添加到图表  方位分别是下和左
    m_chart->addAxis(m_axisX, Qt::AlignBottom);
    m_chart->addAxis(m_axisY, Qt::AlignLeft);

    //关联曲线到坐标轴 
    m_tempSeries->attachAxis(m_axisX);
    m_tempSeries->attachAxis(m_axisY);
    m_humiSeries->attachAxis(m_axisX);
    m_humiSeries->attachAxis(m_axisY);
    
    //这里注意 要先将坐标轴添加到图表,然后再关联曲线到坐标轴。顺序反会报错
    

 QChartView 

       表格视图类,用来存放QChart这个类,但是它还要搭配组件中QGraphicsView类控件,很像套娃(QChart->QChartView->QGraphicsView),其中QGraphicsView类控件要在ui中提升为QChartView类,这样就可以使用setChart()来显示了。

           这样就可以了,我学习别人的文章的时候他们都说要加上

QT_CHARTS_USE_NAMESPACE,或者:using namespace QtCharts;但是可能是QT版本不一样,我的是6.8.3,如果加上后会报错说命令空间错误,删掉以后反而可以正常编译运行。当然QT += charts是一定要的。然后就可以添加视图显示了

    //添加到视图
    ui->Chart_View->setChart(m_chart);  // 将图表对象设置到QgraphicsView控件上进行显示
    ui->Chart_View->setRenderHint(QPainter::Antialiasing); // 抗锯齿,使曲线更平滑

最终效果


运行曲线以及曲线平滑移动

前面0-50还运行的好好的,可是当我运行到50之后,出现了曲线频繁闪动,很不丝滑难受。

曲线很“卡”,看上去,后面思考的时候想,每一次闪动是不是它代表曲线是被重新写入的,并不是一直在添加,而是一直在被重写,我查看代码,原来是在计数大于50之后的逻辑中,我添加了remove(0)这一实现,导致曲线对象在底层逻辑上是进行了删除重写操作,因为会出现“卡”的现象。

        append(a,b);函数就是添加数据操作,a参数为第几个数,b为要插入的数据。

其中被注释的代码就是“罪魁祸首”

    //更新曲线
    m_tempSeries->append(m_dataCount,Temp_Data);
    m_humiSeries->append(m_dataCount,Humi_Data);
    m_dataCount++; //数据计数+1

    //限制x轴显示范围
    if (m_tempSeries->count() > MAX_DATA_POINTS) {
        
        /*
        //去除最旧的一个点
       // 先判断是否有数据可删,避免越界崩溃
       
        if (m_tempSeries->count() > 0) {
            m_tempSeries->remove(0);
        }
        if (m_humiSeries->count() > 0) {
            m_humiSeries->remove(0);
        }
        */  
        // 更新X轴范围(保持显示最新的MAX_DATA_POINTS个点) 
        m_axisX->setRange(m_dataCount - MAX_DATA_POINTS, m_dataCount);

MAX_DATA_POINTS 为 50 (逻辑实现的是:每次往右一个单位,1-51 -> 2-52)

因此只需要利用setRange()函数更新x轴的范围,就可以实现丝滑平移动态曲线,

补充

 例外,如果是这样不去remove(0)它,其实这个对象如果真的在实际中使用很长时间,那会计数到非常大的值,因此优化它的占用空间还是一个值得做的事情,比如可以用QTimer定时器固定时间去清除一定范围的值。再还有对于曲线的平滑优化,让他看起来更丝滑~。

Logo

更多推荐