github:GitHub - supershifeiyu/serial_test: Qt串口数据采集并实时绘图
#-------------------------------------------------
#
# 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
#ifndef CHART_H
#define CHART_H
#include
#include
#include
#include
#include
#include
#include
#include "QDateTime"
#include
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
#ifndef CHART_H
#define CHART_H
#include
#include
#include
#include
#include
#include
#include
#include "QDateTime"
#include
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
#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;
}
#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(&QComboBox::currentIndexChanged),this,&Widget::port_handle);
connect(baud,static_cast(&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;
}
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}