QT实现串口通信和绘图数据保存等功能
嗨好久不见,最近有点偷懒主要是谈甜甜的恋爱去了hh,有个小项目需要用到上位机软件,所以考虑了一下使用QT来做第一个项目。参考了网上一部分教程再加上自己的摸索,哈哈个人认为这是非常完整的一个教程,基本上编译后就能运行,接下来讲一下整个工程的代码逻辑。QT的优点是基本上可以完美移植到其他电脑,但是像labview就不方便,而且labview不好维护。
1 首先看一下我的界面成果
1.1 这是主界面
主界面主要是模仿串口调试助手来的,基本功能接收和定时发送,点击下一页跳到第二个窗口
1.2 第二页窗口
第二页窗口就是数据解析和绘图还是原始数据保存到excel的功能。
2 程序解析
2.1 第一步ui界面的搭建
个人认为对于小白来说,首先得讲一下ui界面的具体每个窗口对应的类型和窗口:
这是第一个界面:
第二个界面:
2.2 第二步看一下我整个工程的目录
main.h:
主要是我的QT库头文件
main.cpp:
main.cpp 自动生成的主函数入口,可以理解就是生成一个QApplication的类a,后面可以调用界面的相关组件。然后 创造一个 Mserialport 的类w,调用w.show() 函数。
mserialport.h:
这里是mserialport.h,我们得配合mserialport.cpp一起来理解
#include "mserialport.h"
#include "ui_mserialport.h"
static int hexsendcheck = 0;
static int hexrecvcheck = 0;
static int sendStopEn = 0;
Mserialport::Mserialport(QWidget *parent) : QWidget(parent), ui(new Ui::Mserialport)
{
ui->setupUi(this);
init();
this->page2=new MainWindow; // 实例化页面2的类
connect(ui->nextPage_2, &QPushButton::clicked,[=](){
// 所谓的切换窗口 就是把主窗体隐藏,第二个页面显示
this->hide(); // 仅仅隐藏, 主窗口页面并没有释放
this->page2->show(); // 显示第二个页面
});
connect(this->page2, &MainWindow::back, [=](){
// 如果不想这么写 单独一个槽函数也是可以
this->page2->hide();
this->show();
});
timSend=new QTimer;
timSend->setInterval(1000);//设置默认值1000ms
connect(timSend,&QTimer::timeout,this,[=]()
{
on_sendButton_released();
});
}
// 析构函数
Mserialport::~Mserialport()
{
delete ui;
}
// 串口初始化
void Mserialport::init()
{
// 获取所有可用的串口
auto portsInfo = QSerialPortInfo::availablePorts();
for (auto& info : portsInfo)
{
qInfo()<<info.description()<<info.portName()<<info.systemLocation();
// 设置串口信息
ui->portsCmb->addItem(info.portName(), info.portName());
}
ui->portsCmb->setCurrentText("COM7");
// 获取标准的波特率
qInfo() << QSerialPortInfo::standardBaudRates();
auto baudRates = QSerialPortInfo::standardBaudRates();
for (auto br:baudRates)
{
ui->baudRateCmb->addItem(QString::number(br),br);
}
ui->baudRateCmb->setCurrentText("115200");
// 设置停止位
ui->stopBitCmb->addItem("1", QSerialPort::OneStop);
ui->stopBitCmb->addItem("1.5", QSerialPort::OneAndHalfStop);
ui->stopBitCmb->addItem("2", QSerialPort::TwoStop);
// 设置数据位
ui->dataBitCmb->addItem("5", QSerialPort::Data5);
ui->dataBitCmb->addItem("6", QSerialPort::Data6);
ui->dataBitCmb->addItem("7", QSerialPort::Data7);
ui->dataBitCmb->addItem("8", QSerialPort::Data8);
ui->dataBitCmb->setCurrentText("8");
// 设置校验位
ui->checkBitCmb->addItem("NoParity", QSerialPort::NoParity);
ui->checkBitCmb->addItem("EvenParity", QSerialPort::EvenParity);
ui->checkBitCmb->addItem("OddParity", QSerialPort::OddParity);
ui->checkBitCmb->addItem("SpaceParity", QSerialPort::SpaceParity);
ui->checkBitCmb->addItem("MarkParity", QSerialPort::MarkParity);
ui->checkBitCmb->setCurrentText("EvenParity");
// 连接
connect(&serialPort_, &QSerialPort::readyRead, this, &Mserialport::onReadyRead);
}
// 按钮打开串口
void Mserialport::on_openPortButton_released()
{
// 首先判断串口是否已经打开
if(serialPort_.isOpen())
{
serialPort_.close();
ui->openPortButton->