Qt 串口数据采集并绘图

VX:13225601016       获取源码和数据集

github:GitHub - supershifeiyu/serial_test: Qt串口数据采集并实时绘图

 serial_test.pro

#-------------------------------------------------
#
# Project created by QtCreator 2022-03-23T20:06:19
#
#-------------------------------------------------

QT       += core gui serialport charts

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = serial_test
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        main.cpp \
        widget.cpp \
    chart.cpp

HEADERS += \
        widget.h \
    chart.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

chart.h

#ifndef CHART_H
#define CHART_H

#include <QtCharts>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QSplineSeries>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QTimer>
#include "QDateTime"
#include <QWidget>

class Chart : public QWidget
{
    Q_OBJECT
public:
    explicit Chart(QWidget *parent = nullptr);
    void init_chart(QString title = tr("无线传输模块调试"), qint16 min =0 ,qint16 max= 30000);//表格初始化
    void draw_line(QDateTime current_time, double number);//画线
    ~Chart();

private slots:

    void save(QDateTime start_time,QDateTime end_time);//保存图表
private:
    QTimer *timer;                           //计时器
    QChartView *chartView;
    QChart *chart;                           //画布
    QSplineSeries *series;                     //线
    QDateTimeAxis *axisX;                    //轴
    QValueAxis *axisY;
};

#endif // CHART_H

widget.h

#ifndef CHART_H
#define CHART_H

#include <QtCharts>
#include <QtCharts/QChart>
#include <QtCharts/QChartView>
#include <QtCharts/QSplineSeries>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QTimer>
#include "QDateTime"
#include <QWidget>

class Chart : public QWidget
{
    Q_OBJECT
public:
    explicit Chart(QWidget *parent = nullptr);
    void init_chart(QString title = tr("无线传输模块调试"), qint16 min =0 ,qint16 max= 30000);//表格初始化
    void draw_line(QDateTime current_time, double number);//画线
    ~Chart();

private slots:

    void save(QDateTime start_time,QDateTime end_time);//保存图表
private:
    QTimer *timer;                           //计时器
    QChartView *chartView;
    QChart *chart;                           //画布
    QSplineSeries *series;                     //线
    QDateTimeAxis *axisX;                    //轴
    QValueAxis *axisY;
};

#endif // CHART_H

chart.cpp

#include "chart.h"

Chart::Chart(QWidget *parent): QWidget(parent)
{
    timer = new QTimer(this);
    timer->start();
    timer->setInterval(1000);    //设置定时周期//创建定时器
}
void Chart::init_chart(QString title, qint16 min,qint16 max)
{
    QPen penY(Qt::darkBlue,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin);
    chartView = new QChartView(this);
    chartView->resize(1600,1000);
    chart = new QChart();
    chart->setTitle(title);
    series = new QSplineSeries;
    axisX = new QDateTimeAxis();
    axisY = new QValueAxis();
    chart->legend()->hide();                             //隐藏图例
    chart->addSeries(series);                            //把线添加到chart
    chart->setTheme(QChart::ChartThemeDark);
    axisX->setTickCount(10);                             //设置坐标轴格数
    axisY->setTickCount(5);
    axisX->setFormat("hh:mm:ss");                        //设置时间显示格式
    axisY->setMin(min);                                    //设置Y轴范围
    axisY->setMax(max);
    axisX->setTitleText("实时时间");                       //设置X轴名称
    axisY->setLinePenColor(QColor(Qt::darkBlue));        //设置坐标轴颜色样式
    axisY->setGridLineColor(QColor(Qt::darkBlue));
    axisY->setGridLineVisible(true);                    //设置Y轴网格显示
    axisY->setLinePen(penY);
    axisX->setLinePen(penY);
    chart->addAxis(axisX,Qt::AlignBottom);               //设置坐标轴位于chart中的位置
    chart->addAxis(axisY,Qt::AlignLeft);
    series->attachAxis(axisX);                           //把数据添加到坐标轴上
    series->attachAxis(axisY);
    axisY->setTitleText("y");
    //把chart显示到窗口上
    chartView->setChart(chart);
    //chartView->setRenderHint(QPainter::Antialiasing);   //设置抗锯齿
}

void Chart::draw_line(QDateTime current_time, double number)
{
    //设置坐标轴显示范围
    chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60 * 1));       //系统当前时间的前一秒
    chart->axisX()->setMax(QDateTime::currentDateTime().addSecs(0));            //系统当前时间                        //这里生成随机数做测试
    //增加新的点到曲线末端
    series->append(current_time.toMSecsSinceEpoch(), number);
}

void Chart::save(QDateTime start_time,QDateTime end_time)
{
    chart->axisX()->setMin(start_time);
    chart->axisX()->setMax(end_time);
    QPixmap p = chartView->grab();
    QImage image = p.toImage();
    QString filename = QFileDialog::getSaveFileName(this,
        tr("Save Image"),
        "",
        tr("*.bmp;; *.png;; *.jpg;; *.tif;; *.GIF")); //选择路径
    if (filename.isEmpty())
    {
        return;
    }
    else
    {
        if (!(image.save(filename))) //保存图像
        {
            QMessageBox::information(this,
                tr("Failed to save the image"),
                tr("Failed to save the image!"));
            return;
        }
    }
}

Chart::~Chart()
{
    delete chart;
}

widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->setFixedSize(1620,1080);
    port = new QComboBox();
    port->addItem(tr("端口号"));
    port->addItem(tr("COM1"));
    port->addItem(tr("COM2"));
    port->addItem(tr("COM3"));
    port->addItem(tr("COM4"));
    port->addItem(tr("COM5"));
    baud = new QComboBox();
    baud->addItem(tr("波特率"));
    baud->addItem(tr("1200"));
    baud->addItem(tr("2400"));
    baud->addItem(tr("4800"));
    baud->addItem(tr("9600"));
    baud->addItem(tr("19200"));
    baud->addItem(tr("38400"));
    baud->addItem(tr("57600"));
    baud->addItem(tr("115200"));
    start = new QPushButton(tr("开始采集"));
    end = new QPushButton(tr("结束采集"));
    QHBoxLayout *top_lay = new QHBoxLayout();//上方布局
    top_lay->addWidget(port,0);
    top_lay->setStretchFactor(port,1);
    top_lay->addWidget(baud,1);
    top_lay->setStretchFactor(baud,1);
    top_lay->addWidget(start,2);
    top_lay->setStretchFactor(start,1);
    top_lay->addWidget(end,3);
    top_lay->setStretchFactor(end,1);
    top_lay->setMargin(10);
    top_lay->setSpacing(5);
    chart = new Chart();
    chart->init_chart("无线模块调试",-100,100);
    QVBoxLayout *main_lay = new QVBoxLayout(this);
    main_lay->addLayout(top_lay,0);
    main_lay->setStretchFactor(top_lay,1);
    main_lay->addWidget(chart,1);
    main_lay->setStretchFactor(main_lay,10);
    main_lay->setMargin(10);
    main_lay->setSpacing(5);
    global_port.setParity(QSerialPort::NoParity);//校验位
    global_port.setDataBits(QSerialPort::Data8);//数据位
    global_port.setStopBits(QSerialPort::OneStop);//停止位
    global_port.setFlowControl(QSerialPort::NoFlowControl);//流控制一般没用
//    global_port.setPortName("COM4");
//    global_port.setBaudRate(QSerialPort::Baud2400);
    connect(start,SIGNAL(clicked()),this,SLOT(start_collect()));
    connect(end,SIGNAL(clicked()),this,SLOT(end_collect()));
    connect(port,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,&Widget::port_handle);
    connect(baud,static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),this,&Widget::baud_handle);
    connect(&global_port ,SIGNAL(readyRead()) , this ,SLOT(on_readyRead()));
}
void Widget::port_handle(int index)//端口号槽函数
{
    switch(port->currentIndex())
    {
    case 1:
    global_port.setPortName("COM1");
        break;
    case 2:
    global_port.setPortName("COM2");
        break;
    case 3:
    global_port.setPortName("COM3");
        break;
    case 4:
    global_port.setPortName("COM4");
        break;
    case 5:
    global_port.setPortName("COM5");
        break;
    }
}
void Widget::baud_handle(int index)//波特率槽函数
{
    switch(baud->currentIndex())
    {
    case 1:
    global_port.setBaudRate(QSerialPort::Baud1200);
        break;
    case 2:
    global_port.setBaudRate(QSerialPort::Baud2400);
        break;
    case 3:
    global_port.setBaudRate(QSerialPort::Baud4800);
        break;
    case 4:
    global_port.setBaudRate(QSerialPort::Baud9600);
        break;
    case 5:
    global_port.setBaudRate(QSerialPort::Baud19200);
        break;
    case 6:
    global_port.setBaudRate(QSerialPort::Baud38400);
        break;
    case 7:
    global_port.setBaudRate(QSerialPort::Baud57600 );
        break;
    case 8:
    global_port.setBaudRate(QSerialPort::Baud115200);
        break;
    }
}
void Widget::start_collect()
{
    qDebug() << global_port.portName() << global_port.baudRate();
    global_port.open(QSerialPort::ReadWrite);
}
void Widget::on_readyRead()
{
    buff = global_port.readAll();
    double number = (buff[0]-'0')*10 + (buff[1]-'0');
    qDebug() << number;
    chart->draw_line(QDateTime::currentDateTime(),number);
}
void Widget::end_collect()
{
    global_port.close();
}
Widget::~Widget()
{
    delete this;
}

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

  • 12
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
### 回答1: 在进行QT串口数据动态曲线显示时,我们首先要借助QT串口通信模块获取来自串口设备的数据。在此基础上,我们需要创建一个QT图形界面程序,来实现曲线的动态显示。 具体而言,我们可以通过QT中的QCustomPlot等图形库来实现动态曲线的显示,在动态显示曲线的同时,我们也需要处理来自串口设备的数据流,将其转化为相应的曲线显示。 在实现QT串口数据动态曲线显示过程中,我们还需要考虑诸如数据采集数据存储和数据处理等问题,以使得此程序更加稳定和实用。 总之,在QT串口数据动态曲线显示中,需要借助QT串口通信模块和相应的图形显示库,同时需要加强对数据采集和处理等问题的考虑,来实现高质量的动态曲线显示功能。 ### 回答2: Qt是一种流行的跨平台GUI开发框架,它提供了许多用于数据可视化的工具。在这篇文章中,我们将讨论如何使用Qt来实现串口数据的动态曲线显示。 首先,我们需要使用Qt串口类来打开串口。通过指定串口的名称、波特率、数据位数、校验位和停止位等参数,我们可以创建一个可以读取或写入串口数据的对象。 一旦这个串口对象被创建,我们就可以通过Qt的信号槽机制来处理接收到的串口数据。我们可以连接一个槽函数到读取串口数据的信号上,每当串口收到数据时,该槽函数就会自动被调用,并将串口数据存储到一个缓冲区中。 接下来,我们需要使用Qt绘图类来将串口数据转换成一条曲线。通过创建一个QPainter对象,我们可以在一个QWidget窗口上实现实时数据曲线的动态显示。我们可以使用QPainter的绘制函数,如drawLine、drawPoint或drawPath,来把每个新的数据点添加到曲线中。 最后,我们需要使用Qt的定时器类来控制实时数据曲线的更新速率。通过使用QTimer类的start和stop函数,我们可以启动和停止一个定时器对象,以定期调用更新显示函数,这样就可以实现实时数据曲线的动态显示。 综上所述,使用Qt实现串口数据的动态曲线显示并不复杂。我们只需要利用Qt串口、信号槽、绘图和定时器等类,就可以轻松地实现一个可靠的功能强大的实时数据曲线显示系统。 ### 回答3: 在Qt中进行串口数据的动态曲线显示,可以利用Qt Charts模块以及Qt SerialPort模块。首先需要打开串口,读取串口数据并解析,将解析后的数据作为动态曲线的横纵坐标,并将数据实时显示在曲线上。 具体步骤如下: 1. 引入Qt Charts和Qt SerialPort模块,包括头文件和库文件。 2. 在UI界面中添加一个动态曲线控件,设置相关属性,如横纵坐标范围、坐标轴标签等。 3. 打开串口,设置串口参数,如波特率、数据位、停止位等。 4. 读取串口数据,使用Qt的QSerialPort类中的read()函数读取数据,读取后进行解析。 5. 将解析后的数据作为动态曲线的横纵坐标,使用Qt Charts中的QChart类和QLineSeries类,将坐标点添加到曲线中,并通过曲线的update()函数进行实时更新。 6. 将实时更新的曲线显示在UI界面中,使用Qt的QChartView类将曲线添加到UI中的曲线控件中。 7. 完成后需要在程序中添加相应的错误处理和异常处理代码。当串口连接错误或数据解析错误时,应该及时给出提示信息。 以上是Qt串口数据动态曲线显示的基本步骤,根据实际需求可以进行一些扩展和优化。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计科 执念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值