首页 > 其他分享 >qt中使用qwt实现实时曲线显示(转)

qt中使用qwt实现实时曲线显示(转)

时间:2023-01-12 09:13:27浏览次数:60  
标签:TimeSerialData const qt void 曲线 value 实时 qwt id

QT中使用QWT实现实时曲线显示

 

最近做一个飞控的上位机,需要实时在一个图中显示多条曲线,并且这些曲线还可以在任何时刻隐藏和显示。于是借鉴qgc地面站中显示mavlink消息的曲线显示方法,用qwt实现了这一功能。

最终效果

在这里插入图片描述
可以设置任意曲线是否显示,
在这里插入图片描述
还可以设置背景颜色。

滑动效果
在这里插入图片描述

问题分析:

首先,曲线图需要网格定义,曲线宽度,曲线颜色等基本的信息,可以写一个基类,把这些基本信息写到里面。然后在继承类中增加曲线添加,单条曲线显示,单条曲线隐藏,更新曲线数据等方法。最后,为了使曲线在图上运动起来,还需要一个队列来保存前多少时间的时序数据,这也用一个类来实现。

QWT配置:

首先下载qwt的源码,然后打开pro后缀的qt工程,进行编译(注意是32位还是64位)。编译完成后会出现qwtd.lib,qwt.lib,qwtd.dll,qwt.dll。
如果是5.9版本的msvc2015 64位,则把lib文件放到Qt5.9.0\5.9\msvc2015_64\lib目录下,把dll文件放到D:\Qt\Qt5.9.0\5.9\msvc2015_64\bin目录下。如果是32位,则放到32位对应的目录下。

同时会生成: qwt_designer_plugin.dll文件,这个文件必须是32位的,把dll文件放到Qt5.9.0\Tools\QtCreator\bin\plugins\designer目录下即可。这一步也可以不做,这样的话就不能拖控件实现布局,需要在代码中定义控件。

然后重启qt,打开界面设计,会看到有新的控件出现:
在这里插入图片描述
如果要使用qwt提高的图表,在新建的工程中还需要在pro文件中添加如下语句:

CONFIG(debug, debug|release) {
LIBS += D:\Qt\Qt5.9.0\5.9\msvc2015_64\lib\qwtd.lib
} else {
LIBS += D:\Qt\Qt5.9.0\5.9\msvc2015_64\lib\qwt.lib
}

DEFINES += QT_DLL QWT_DLL
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

代码:

储存曲线图基本信息的类,需要继承自QwtPlot

主要有这些成员

void appendData(QString dataname, quint64 ms, double value);
void setVisibleById(QString id, bool visible);
void hideCurve(QString id);
void showCurve(QString id);
void setCurveColor(QString id, QColor color);
void addCurve(QString id);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

同时定义如下变量:

QMap<QString, TimeSerialData*> _data;    //用于存放所以系列数据
QMap<QString, QwtPlotCurve* >   _curves;    //用于存放所以曲线
  • 1
  • 2

添加曲线时:

void addCurve(QString id)
{
    QColor currentColor = getNextColor();

    // Create new curve and set style
    QwtPlotCurve* curve = new QwtPlotCurve(id);
    // Add curve to list
    _curves.insert(id, curve);

    curve->setStyle(QwtPlotCurve::Lines);
    curve->setPaintAttribute(QwtPlotCurve::FilterPoints, true);
    setCurveColor(id, currentColor);
    curve->setLegendAttribute(curve->LegendShowLine);
    curve->attach(this);

    // Create dataset
    TimeSerialData* dataset = new TimeSerialData();

    // Add dataset to list
    _data.insert(id, dataset);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

显示和隐藏曲线:

void setVisibleById(QString id, bool visible)
{
    if(_curves.contains(id))
    {
        _curves.value(id)->setVisible(visible);
        if(visible)
            _curves.value(id)->attach(this);
        else
            _curves.value(id)->detach();
    }
}

void hideCurve(QString id)
{
    setVisibleById(id, false);
}

void showCurve(QString id)
{
    setVisibleById(id, true);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

给曲线附加数据时:

void appendData(QString dataname, quint64 time, double value)
{
    datalock.lock();
    if(!data.contains(dataname))
        addCurve(dataname);
    TimeSerialData* dataset = _data.value(dataname);

    dataset->append(time, value);

    QwtPlotCurve* curve = _curves.value(dataname);
    curve->setRawSamples(dataset->getPlotX(), dataset->getPlotY(), dataset->getPlotCount());

    setAxisScale(QwtPlot::xBottom, dataset->getmsstart(), dataset->getmsstop(),10.0);
    setAxisScale(QwtPlot::yLeft,-30,30,5);
    datalock.unlock();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

时间序列的类

头文件

#ifndef TIMESERIALDATA_H
#define TIMESERIALDATA_H
#include <QVector>
#include <QMutex>

class TimeSerialData
{
public:
    TimeSerialData();

    void append(quint64 ms, double value);

    int getCount() const;

    const double* getPlotX() const;
    const double* getPlotY() const;
    int getPlotCount() const;

    int getmsstart(){return ms.at(0);}
    int getmsstop(){return ms.at(ms.size()-1);}

    QMutex dataMutex;
private:

    QVector<double> ms;
    QVector<double> value;
    double maxValue;
    double minValue;
    int count;
    int maxsize;
};

#endif // TIMESERIALDATA_H

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

cpp文件:

#include "timeserialdata.h"

TimeSerialData::TimeSerialData()
{
    count = 0;
    maxsize = 100;
    maxValue = -100000;
    minValue = 100000;
}

int TimeSerialData::getCount() const
{
    return count;
}

int TimeSerialData::getPlotCount() const
{
    if(count>maxsize)
        return maxsize;
    return count;
}

const double* TimeSerialData::getPlotX() const
{
    return ms.data();
}

const double* TimeSerialData::getPlotY() const
{
    return value.data();
}

void TimeSerialData::append(quint64 ms, double value)
{
    dataMutex.lock();
    count++;
    // Qt will automatically use a smart growth strategy: http://doc.qt.io/qt-5/containers.html#growth-strategies
    this->ms.append(ms);
    this->value.append(value);

    if(minValue > value) minValue = value;
    if(maxValue < value) maxValue = value;

    if(count >maxsize )
    {
        this->ms.pop_front();
        this->value.pop_front();
    }

    dataMutex.unlock();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

该类主要用来储存时间序列的队列,只保存前100帧数据,使用QVector进行队列维护。可以计算当前数据坐标范围,返回需要显示的数据块指针。

原文链接:https://blog.csdn.net/iamqianrenzhan/article/details/90054037

标签:TimeSerialData,const,qt,void,曲线,value,实时,qwt,id
From: https://www.cnblogs.com/xihong2014/p/17045455.html

相关文章