Qt qextserial进行串口数据采集,qcustomplot进行绘图,曲线实时显示横纵坐标辅助线

Qt qextserial进行串口数据采集,qcustomplot进行绘图,曲线实时显示横纵坐标辅助线

目的、要求:

A.读取RS422接口接收到的全部数据;

1.通过接口读取板卡采集的数据,采用多线程,读取数据和解析数据在主线程,绘制曲线在另一个新的线程。COM和API接口见附件1.板卡用户手册。

2.根据接收到的数据,需要先判定是返参帧A还是返参帧B,每一帧具有27个字节,每帧依据“帧头”和“校验和”来判定。

需要注意:

a)数据流起始位置并不一定是“帧头”。

b)数据流中可能存在无效的数据包,需要注意判定逻辑,以免丢失有效数据。

B.能够依据协议对数据进行解析并存储;

1.要求对返参帧A和返参帧B数据分别解析,详细的解析与处理要求见附件2。附件2中需要用到的解析协议见附件3。

2.将接收到的返参帧A和返参帧B分别存储在文档不同的sheet中,文档格式为".xlsx",允许用户在软件界面上以点击按钮的形式选择数据存储开始/结束,允许用户选择设置路径。

3.存储内容包括附件2表中全部解析内容,每一项解析内容对应存储在文档中一列,存储数据为解析后未经数据处理的数据。

C.对解析后的一些数据,以曲线的形式显示。

1.软件需对返参帧A和返参帧B的部分解析内容进行实时曲线绘制,需要绘制曲线的参数见附件4。共15个曲线图。

2.通过“选项卡”的形式将不同类型曲线放置在不同选项卡页面中。

3.要求曲线能根据接收解析后的数据点进行动态实时更新,从右向左,横坐标代表点的个数,曲线对应的横坐标刻度要一同向左更新移动。

4.要求曲线窗口有图标题,有横纵坐标标题;如果一个曲线窗口中有多条曲线,要求用不同颜色区分,对不同曲线有标注;用户可选择仅显示其中某一条或某两条曲线;

5.曲线要求正常显示为1000个数据点,缓存区要求存180000个数据点,可在曲线窗口上左右拖拽以查看180000中的各个1000个数据点的显示区间,超出180000个数据点缓存区后,每进入一个新的数据点,则顺次清除一个原数据点。曲线横、纵坐标范围允许用户调整,可进行2、4、6、8倍的4档放大曲线局部判读。

6.鼠标移动到曲线上的数据点上时,要求有指向横、纵坐标的辅助线。

简介:

考虑到这个要移植到硬件上,到时候交叉编译后的Qt环境需要串口模块的支持。所以选用了第三方的chua串口通讯模块qextserial进行串口通讯。绘图使用的第三方的qcustomplot。串口模块放到线程里,数据处理和绘图部分放到了主线程。这个地方主要麻烦的是对通讯帧的解析。首先分为A B两种mo's模式,每个字节对应的有不同的含义。有些字节的某几位对应的不同的含义。剩下的就是数据的辅助线问题了。辅助线继承了QCustomPlot,然后重写了鼠标事件和其他的一些事件。

效果:

代码:

#ifndef MHCUSTOMPLOT_H
#define MHCUSTOMPLOT_H

#include "mhtracer.h"
#include "qcustomplot.h"
#include <QObject>
#include <QList>

class MhCustomPlot : public QCustomPlot
{
    Q_OBJECT
public:
    MhCustomPlot(QWidget *parent = 0);

protected:
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void enterEvent(QEvent *event);
    virtual void leaveEvent(QEvent *event);
    //virtual void mouseDoubleClickEvent(QMouseEvent *event);
//signals:
    //void legendDoubleClickChilden(QCPLegend *legend,  QCPAbstractLegendItem *item, QMouseEvent *event);
public:
    //设置是否显示鼠标追踪器
    //是否显示
    void showTracer(bool show);
    // 是否显示鼠标追踪器
    bool isShowTracer(){return m_isShowTracer;}

private:
    bool m_isShowTracer;//是否显示追踪器(鼠标在图中移动,显示对应的值)
    MhTracer *m_xTracer;//x轴
    MhTracer *m_yTracer;//y轴
    QList<MhTracer *> m_dataTracers;//
    MhTraceLine  *m_lineTracer;//直线
};

#endif // MHCUSTOMPLOT_H
#include "mhcustomplot.h"

MhCustomPlot::MhCustomPlot(QWidget *parent)
    :QCustomPlot(parent)
    ,m_isShowTracer(false)
    ,m_xTracer(Q_NULLPTR)
    ,m_yTracer(Q_NULLPTR)
    ,m_dataTracers(QList<MhTracer *>())
    ,m_lineTracer(Q_NULLPTR)
{

}
//设置是否显示鼠标追踪器
//是否显示
void MhCustomPlot::showTracer(bool show)
{
    m_isShowTracer = show;
    if(m_xTracer)
        m_xTracer->setVisible(m_isShowTracer);
    ///
    if(m_yTracer)
    {
        m_yTracer->setVisible(m_isShowTracer);
    }
    foreach (MhTracer *tracer, m_dataTracers)
    {
        if(tracer)
            tracer->setVisible(m_isShowTracer);
    }
    if(m_lineTracer)
        m_lineTracer->setVisible(m_isShowTracer);
}

void MhCustomPlot::mouseMoveEvent(QMouseEvent *event)
{
    QCustomPlot::mouseMoveEvent(event);

    if(m_isShowTracer)
    {
        //当前鼠标位置(像素坐标)
        int x_pos = event->pos().x();
        int y_pos = event->pos().y();

        //qDebug() << "x_pos:" << x_pos << "y_pos:" << y_pos;

        //像素坐标转成实际的x,y轴的坐标
        float x_val = this->xAxis->pixelToCoord(x_pos);
        float y_val = this->yAxis->pixelToCoord(y_pos);

        if(Q_NULLPTR == m_xTracer)
            m_xTracer = new MhTracer(this, MhTracer::XAxisTracer);//x轴
        m_xTracer->updatePosition(x_val, y_val);

        if(Q_NULLPTR == m_yTracer)
            m_yTracer = new MhTracer(this, MhTracer::YAxisTracer);//y轴
        m_yTracer->updatePosition(x_val, y_val);

        int nTracerCount = m_dataTracers.count();
        int nGraphCount = graphCount();
        if(nTracerCount < nGraphCount)
        {
            for(int i = nTracerCount; i < nGraphCount; ++i)
            {
                MhTracer *tracer = new MhTracer(this, MhTracer::DataTracer);
                m_dataTracers.append(tracer);
            }
        }
        else if(nTracerCount > nGraphCount)
        {
            for(int i = nGraphCount; i < nTracerCount; ++i)
            {
                MhTracer *tracer = m_dataTracers[i];
                if(tracer)
                {
                    tracer->setVisible(false);
                }
            }
        }
        for (int i = 0; i < nGraphCount; ++i)
        {
            MhTracer *tracer = m_dataTracers[i];
            if(!tracer)
                tracer = new MhTracer(this, MhTracer::DataTracer);
            tracer->setVisible(true);
            tracer->setPen(this->graph(i)->pen());
            tracer->setBrush(Qt::NoBrush);
            tracer->setLabelPen(this->graph(i)->pen());
            auto iter = this->graph(i)->data()->findBegin(x_val);
            double value = iter->mainValue();
//            double value = this->graph(i)->data()->findBegin(x_val)->value;
            tracer->updatePosition(x_val, value);
        }

        if(Q_NULLPTR == m_lineTracer)
            m_lineTracer = new MhTraceLine(this,MhTraceLine::Both);//直线
        m_lineTracer->updatePosition(x_val, y_val);

        this->replot(QCustomPlot::rpQueuedReplot);//曲线重绘
    }
}

void MhCustomPlot::enterEvent(QEvent *event)
{
    //QCustomPlot::enterEvent(event);
    //qDebug() << "鼠标进入";
    m_isShowTracer = true;
    if(m_xTracer)
        m_xTracer->setVisible(m_isShowTracer);
    if(m_yTracer)
    {
        m_yTracer->setVisible(m_isShowTracer);
    }
    foreach (MhTracer *tracer, m_dataTracers)
    {
        if(tracer)
            tracer->setVisible(m_isShowTracer);

    }
    if(m_lineTracer)
        m_lineTracer->setVisible(m_isShowTracer);
    this->replot(QCustomPlot::rpQueuedReplot);
}

void MhCustomPlot::leaveEvent(QEvent *event)
{
    //QCustomPlot::leaveEvent(event);
    //qDebug() << "鼠标离开";
    m_isShowTracer = false;
    if(m_xTracer)
        m_xTracer->setVisible(m_isShowTracer);
    if(m_yTracer)
    {
        m_yTracer->setVisible(m_isShowTracer);
    }
    foreach (MhTracer *tracer, m_dataTracers)
    {
        if(tracer)
            tracer->setVisible(m_isShowTracer);
    }
    if(m_lineTracer)
        m_lineTracer->setVisible(m_isShowTracer);
    this->replot(QCustomPlot::rpQueuedReplot);
}

//void MhCustomPlot::mouseDoubleClickEvent(QMouseEvent *event)
//{
//    QCustomPlot::mouseDoubleClickEvent(event);
//}

 

exe地址(百度网盘链接):

链接:https://pan.baidu.com/s/1YeYbY32FM1Ol1FKvdLUUJA 
提取码:tr0d 

QQ:921673516  QQ群:511450936  邮箱:yue_xusy@163.com

  • 7
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在Qt5中使用QCustomPlot显示实时曲线可以分为以下几个步骤: 1. 首先,需要在Qt项目中添加QCustomPlot库。可以通过在.pro文件中添加`LIBS += -lqcustomplot`来链接该库。 2. 在界面上添加一个QCustomPlot控件,可以通过Qt设计器拖放方式或者手动添加。 3. 创建一个类来处理数据的更新和绘图操作。这个类需要继承QObject和QCustomPlot类,并且实现一个槽函数用于接收新的数据。我们可以将这个类称为RealtimePlot。 4. 在RealtimePlot类的构造函数中初始化QCustomPlot控件,并设置相关属性,如坐标范围、轴标签等。 5. 在RealtimePlot类中实现绘制曲线的方法,可以使用QCPGraph对象来表示曲线,并使用addData()方法来添加新的数据点。 6. 在RealtimePlot类中实现一个槽函数,用于接收新的数据。当有新的数据到达时,将其添加到QCustomPlot控件中,并调用replot()方法进行重绘。 7. 在主窗口类中创建一个实例对象,以便在主窗口中显示实时曲线。可以将RealtimePlot作为主窗口的成员变量,然后在构造函数中初始化。 8. 在主窗口类中启动一个定时器,可以使用QTimer类来定时获取新的数据并发送给RealtimePlot对象。 以上就是使用Qt5和QCustomPlot显示实时曲线的基本步骤,具体的实现方式可能会依据个人或项目的需求略有不同。 ### 回答2: 在Qt5中,可以使用QCustomPlot库来显示实时曲线。 首先,需要在项目中引入QCustomPlot库。可以将该库的头文件和源文件添加到项目中,并在.pro文件中添加相应的配置。 接下来,在要显示实时曲线的窗口中创建一个QCustomPlot对象,作为曲线绘图区域。 然后,可以通过QTimer来定时更新曲线数据。创建一个QTimer对象,并设置其定时器的时间间隔。 在定时器的槽函数中,可以更新曲线数据。首先,获取QCustomPlot的坐标轴对象,然后使用addData()函数添加新的数据点。可以通过setDataRange()函数来设置坐标轴的范围。 最后,调用replot()函数来刷新曲线显示。 下面是一个简单的示例: ``` // MainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "qcustomplot.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: QCustomPlot *m_plot; QTimer *m_timer; QVector<double> m_data; int m_count; private slots: void updateData(); }; #endif // MAINWINDOW_H // MainWindow.cpp #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { m_plot = new QCustomPlot(this); setCentralWidget(m_plot); m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(updateData())); m_timer->start(1000); // 定时器间隔为1秒 m_data.resize(100); m_count = 0; } MainWindow::~MainWindow() { delete m_timer; } void MainWindow::updateData() { m_data.removeFirst(); m_data.append(qrand() % 100); m_plot->graph(0)->setData(QVector<double>::fromStdVector(m_data.toStdVector())); m_plot->xAxis->setRange(0, m_count); m_plot->replot(); m_count++; } ``` 通过以上代码,就可以在Qt5中使用QCustomPlot显示实时曲线了。可以根据实际需求进行相应的调整,例如添加不同的曲线、设置坐标轴、定时器间隔等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值