
正文
<QT之Bug制造机>QT中串口类“QSerialPort”的学习笔记
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
QT5中已经增加了串口类QSrialPort,可以直接调用API函数进行快速开发。

注意qmake那边:QT += serialport。要把QT += serialport在加到.pro文件中
1. 获取串口信息
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
const auto infos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : infos)
serialPortComboBox->addItem(info.portName());
}
- QSerialPortInfo::availablePorts()

函数的功能时会检测当前电脑上串行端口,并且返回系统上串行端口的信息。
之后将获取到的信息加入Qcombobox下拉选项框中。本例中只添加了串口的名字即COM4。
2.设置串口参数并开启串口
void Dialog::openSerial()
{
if(runButton->text() == tr("开启"))
{
serial = new QSerialPort(); //port name
serial->setPortName(serialPortComboBox->currentText()); //open
serial->open(QIODevice::ReadWrite); serial->setBaudRate();
serial->setDataBits(QSerialPort::Data8);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
/* 一定要写,不然串口接收不到数据 */
connect(serial, SIGNAL(readyRead()), this, SLOT(readParam())); runButton->setText("关闭");
}
else
{
serial->clear();
serial->close();
serial->deleteLater(); runButton->setText("开启");
}
}connect(serial, SIGNAL(readyRead()), this, SLOT(readParam()));
该函数是启动串口接收功能。即当串口有数据时,readyRead()信号就会被抛出。对应的readParam()即QT中所定义的槽就会被调用。注意:
readyRead()信号是有数据就直接抛出,在实际数据交互中,往往一帧数据有很多字节。这意味着我们一帧数据数据会触发多次信号。应当在对数据进行操作时候对数据进行校验。
3.串口发送数据
serial->write(sendData);
sendData为QByteArray类所创建的对象,即数据缓存区。
4.串口接收数据
g_RecBuf.append(serial->readAll());

readAll函数会读取当前设备所有剩余数据,并将它作为字节数组返回。
以上实例源码:
dialog.cpp
#include "dialog.h"
#include <QDebug>
#include <QThread>
#include <QTimer>Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
serialPortComboBox = new QComboBox();
readParaBox = new QComboBox();
writeParaBox = new QComboBox();
runButton = new QPushButton(tr("开启"));
readPara = new QPushButton(tr("读取参数"));
writePara = new QPushButton(tr("下发参数"));
onlyOneRead = new QPushButton(tr("一键读取"));
onlyOneWrite = new QPushButton(tr("一键下发"));
cmd = readFlag; timer = new QTimer(); /* add comprot into combobox item */
const auto infos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : infos)
serialPortComboBox->addItem(info.portName()); readParaBox->addItem(tr("读取参数地址1"));
readParaBox->addItem(tr("读取参数地址2"));
readParaBox->addItem(tr("读取参数地址3"));
readParaBox->addItem(tr("读取参数地址4"));
readParaBox->addItem(tr("读取参数地址5")); writeParaBox->addItem(tr("下发参数地址1"));
writeParaBox->addItem(tr("下发参数地址2"));
writeParaBox->addItem(tr("下发参数地址3"));
writeParaBox->addItem(tr("下发参数地址4"));
writeParaBox->addItem(tr("下发参数地址5")); auto mainLayout = new QGridLayout;
mainLayout->addWidget(serialPortComboBox, 0, 0);
mainLayout->addWidget(runButton, 0, 1);
mainLayout->addWidget(readParaBox,1,0);
mainLayout->addWidget(readPara, 1, 1);
mainLayout->addWidget(writeParaBox,2,0);
mainLayout->addWidget(writePara, 2, 1);
mainLayout->addWidget(onlyOneRead,3,0);
mainLayout->addWidget(onlyOneWrite,3,1);
setLayout(mainLayout); connect(runButton, &QPushButton::clicked, this, &Dialog::openSerial);
connect(readPara, &QPushButton::clicked, this, &Dialog::sendCmd);
connect(writePara, &QPushButton::clicked, this, &Dialog::writeParam);
connect(timer, SIGNAL(timeout()), this, SLOT(timerStop()));
connect(onlyOneRead,&QPushButton::clicked,this,&Dialog::oneRead);
connect(onlyOneWrite,&QPushButton::clicked,this,&Dialog::oneWrite);
}void Dialog::openSerial()
{
if(runButton->text() == tr("开启"))
{
serial = new QSerialPort(); //port name
serial->setPortName(serialPortComboBox->currentText()); //open
serial->open(QIODevice::ReadWrite); serial->setBaudRate(115200);
serial->setDataBits(QSerialPort::Data8);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl); connect(serial, SIGNAL(readyRead()), this, SLOT(readParam())); runButton->setText("关闭");
}
else
{
serial->clear();
serial->close();
serial->deleteLater(); runButton->setText("开启");
}
}void Dialog::writeParam(void)
{
QByteArray sendData;
sendData.resize(1026); QString strWriteFile = writeParaBox->currentText();
strWriteFile.append(".dat"); if(strWriteFile == "下发参数地址1.dat")
{
file.setFileName("读取参数地址1.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址2.dat")
{
file.setFileName("读取参数地址2.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址3.dat")
{
file.setFileName("读取参数地址3.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址4.dat")
{
file.setFileName("读取参数地址4.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
else if(strWriteFile == "下发参数地址5.dat")
{
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
}
file.close();
sendData.clear();
}void Dialog::timerStop(void)
{
g_RecBuf.prepend(0xBB); timer->stop();
{
QByteArray leftAck = g_RecBuf.left(2);
QByteArray rightAck = g_RecBuf.right(1); QByteArray byte1;
QByteArray byte2; byte1.append(0xBB);
byte1.append(0xAA);
byte2.append(0xFF); if(g_RecBuf.size() > 30)
{
Dialog::saveDataToFile(g_RecBuf);
}
else if(leftAck == byte1 && rightAck == byte2 && cmd == writeFlag)
{
cmd = readFlag;
msglabel = new QLabel();
QMessageBox::question(this,tr("提示"),tr("下发参数成功"), QMessageBox::Ok);
}
}
g_RecBuf.clear();
}void Dialog::readParam()
{
timer->start(100);
g_RecBuf.append(serial->readAll());
}/* Function: Dialog::saveDataToFile
* Describe: Save the data from serial into File
*/
void Dialog::saveDataToFile(QByteArray &data)
{
if(cmd == readFlag)
{
QString strFileName = readParaBox->currentText(); file.setFileName(strFileName.append(".dat"));
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
} if(cmd != readFlag)
{
switch (cmd) {
case cmd1:
file.setFileName("读取参数地址1.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break; case cmd2:
file.setFileName("读取参数地址2.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break; case cmd3:
file.setFileName("读取参数地址3.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break; case cmd4:
file.setFileName("读取参数地址4.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
Dialog::oneRead();
break; case cmd5:
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::WriteOnly))
{
file.write(data);
}
file.close();
cmd = readFlag;
break;
default:
break;
}
}
}void Dialog::sendCmd(void)
{
QByteArray sendpara; unsigned char zero = 0x00; if(readParaBox->currentText() == tr("读取参数地址1"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x01);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址2"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x02);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址3"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x03);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址4"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x04);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
}
else if(readParaBox->currentText() == tr("读取参数地址5"))
{
sendpara.append(0xAA);
sendpara.append(0x33);
sendpara.append(0x05);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(zero);
sendpara.append(0xFF);
} serial->write(sendpara);
sendpara.clear();
}void Dialog::oneRead(void)
{
QByteArray cmdArray;
unsigned char zero = 0x00; switch (cmd) {
case readFlag:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x01);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd1; serial->write(cmdArray);
cmdArray.clear();
break; case cmd1:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x02);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd2; serial->write(cmdArray);
cmdArray.clear();
break; case cmd2:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x03);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd3; serial->write(cmdArray);
cmdArray.clear();
break; case cmd3:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x04);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd4; serial->write(cmdArray);
cmdArray.clear();
break; case cmd4:
cmdArray.append(0xAA);
cmdArray.append(0x33);
cmdArray.append(0x05);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(zero);
cmdArray.append(0xFF);
cmd = cmd5; serial->write(cmdArray);
cmdArray.clear();
break;
}
}void Dialog::oneWrite(void)
{
QByteArray sendData;
sendData.resize(1026); file.setFileName("读取参数地址1.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear(); file.setFileName("读取参数地址2.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear(); file.setFileName("读取参数地址3.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear(); file.setFileName("读取参数地址4.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
#if 0
file.setFileName("读取参数地址5.dat");
if(file.open(QFile::ReadOnly))
{
sendData = file.readAll();
serial->write(sendData);
}
file.close();
sendData.clear();
#endif cmd = writeFlag;
}Dialog::~Dialog()
{}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>#include <QComboBox>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTimer>
#include <QMessageBox>enum enumType
{
readFlag,
cmd1,
cmd2,
cmd3,
cmd4,
cmd5,
writeFlag
};class Dialog : public QDialog
{
Q_OBJECTpublic:
Dialog(QWidget *parent = 0);
~Dialog();private slots:
void openSerial(void);
void writeParam(void);
void sendCmd(void);
void timerStop(void);
void readParam(void);
void oneRead(void);
void oneWrite(void);private:
void saveDataToFile(QByteArray &data);private:
QComboBox *serialPortComboBox;
QComboBox *readParaBox;
QComboBox *writeParaBox; QPushButton *runButton;
QPushButton *readPara;
QPushButton *writePara;
QPushButton *onlyOneRead;
QPushButton *onlyOneWrite; QLabel *msglabel;
QSerialPort *serial;
QTimer *timer;
QFile file;
QByteArray g_RecBuf; unsigned int Flag; enumType cmd;
};#endif // DIALOG_H
运行效果:

作用就是通过串口发送以及接收一些数据。
<QT之Bug制造机>QT中串口类“QSerialPort”的学习笔记的更多相关文章- Qt 串口类QSerialPort 使用笔记
Qt 串口类QSerialPort 使用笔记 虽然现在大多数的家用PC机上已经不提供RS232接口了.但是由于RS232串口操作简单.通讯可靠,在工业领域中仍然有大量的应用.Qt以前的版本中,没有提供 ...
- c++中的类(class)-----笔记(类模板)
1,一个模板类至少具有一个类参数,类参数是个符号以表示将要被某个确定数据类型代替的类型. #include<iostream> #include<string> using n ...
- c++中的类(class)-----笔记(类继承)
1,派生类继承了基类的所有成员函数和数据成员(构造函数.析构函数和操作符重载函数外). 2,当不指明继承方式时,默认为私有继承. 3,基类的私有成员仅在基类中可见,在派生类中是不可见的.基类的私有成员 ...
- javascript类和原型学习笔记
js中类的所有实例对象都从同一个原型对象上继承属性.我们可以自己写一个对象创建的工厂方法来来"模拟"这种继承行为: //inherit()返回一个继承自原型对象p的属性的性对象 / ...
- Delphi中Chrome Chromium、Cef3学习笔记(三)
原文 http://blog.csdn.net/xtfnpgy/article/details/46635871 Delphi与JS的交互问题: 一.执行简单的JS 上一篇已经讲过: chrm ...
- C#同步,异步的理解,包括5.0中await和async(学习笔记)
之前在工作中一直用的是同步线程,就是先进入画面的load事件,然后在里面进行数据库调用的处理.后面又遇到了公司软件中一些比较古老的代码,一开始在那块古老代码中增加机能的时候,我想用到数据库的数据给画面 ...
- java中File类的相关学习
File类 1.关于系统路径分割符. 在Windows中,使用反斜杠“\”作为路径分割符,比如“c:\test”,但是java中反斜杠表示转义,所以需要用“C:\\test”在程序中来表示路径.还可以 ...
- c++中的类(class)-----笔记(类多态)
1,多态是一种运行期绑定机制,通过这种机制,实现将函数名绑定到函数具体实现代码的目的.一个函数的名称与其入口地址是紧密相连的,入口地址是该函数在内存中的起始地址.如果对一个函数的绑定发生在运行时刻而非 ...
- c++中的类(class)-----笔记(类简介)
1, class 和 struct 都可以定义一个类,区别是两者在所支持的 默认信息隐藏方式不同:c++ 中默认为 private 类型,而 struct 中默认为 public 类型. 2,类的私有 ...
随机推荐- 用大白话聊聊JavaSE -- 如何理解Java Bean(一)
首先,在开始本章之前,先说一个总的概念:所谓的Java Bean,就是一个java类,编译后成为了一个后缀名是 .class的文件.这就是Java Bean,很多初学者,包括当年的我自己,总是被这些专 ...
- OpenModelica仿真
复杂产品通常涉及机械.控制.电子.液压.气动和软件等多学科领域,其设计过程需要进行仿真,以满足对成本.质量.性能等的要求.目前各个学科和领域都已经有了比较成熟的仿真软件,但大部分仿真软件仅适用于本学科 ...
- 微信小视频复制到手机本地Android APP 分享
因为需要将拍的宝宝的微信小视频上传到亲宝宝软件,每次去手动找文件比较麻烦,所以做了个微信视频复制到手机本地的APP,做工虽然粗糙,但是绝对实用, 下载地址 http://pan.baidu.com/s ...
- 4..一起来学hibernate之Session详解
后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续...
- [团队项目]SCRUM项目6.0 7.0 (新)
6.0----------------------------------------------------- sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果得到认可,会感觉 ...
- 【总结】Java线程同步机制深刻阐述
原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...
- display: inline-block 的神奇效果
先上要实现的效果图: 方案一:来自卢兄: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 通用的星星类已经完成了,下面我们来实现具体的变长和缩短道具. 变 ...
- java面试题复习(六)
51.实现多线程的方法 一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如 ...
- 《A_Pancers》第一次作业:团队亮相
一.团队及团队成员介绍 1> 队名:A_Pancers 2> 团队成员组成: 201571030310/龙正圆(小组长) 201571030329/杨环宇 20157103030 ...
Qt 串口类QSerialPort 使用笔记 虽然现在大多数的家用PC机上已经不提供RS232接口了.但是由于RS232串口操作简单.通讯可靠,在工业领域中仍然有大量的应用.Qt以前的版本中,没有提供 ...
1,一个模板类至少具有一个类参数,类参数是个符号以表示将要被某个确定数据类型代替的类型. #include<iostream> #include<string> using n ...
1,派生类继承了基类的所有成员函数和数据成员(构造函数.析构函数和操作符重载函数外). 2,当不指明继承方式时,默认为私有继承. 3,基类的私有成员仅在基类中可见,在派生类中是不可见的.基类的私有成员 ...
js中类的所有实例对象都从同一个原型对象上继承属性.我们可以自己写一个对象创建的工厂方法来来"模拟"这种继承行为: //inherit()返回一个继承自原型对象p的属性的性对象 / ...
原文 http://blog.csdn.net/xtfnpgy/article/details/46635871 Delphi与JS的交互问题: 一.执行简单的JS 上一篇已经讲过: chrm ...
之前在工作中一直用的是同步线程,就是先进入画面的load事件,然后在里面进行数据库调用的处理.后面又遇到了公司软件中一些比较古老的代码,一开始在那块古老代码中增加机能的时候,我想用到数据库的数据给画面 ...
File类 1.关于系统路径分割符. 在Windows中,使用反斜杠“\”作为路径分割符,比如“c:\test”,但是java中反斜杠表示转义,所以需要用“C:\\test”在程序中来表示路径.还可以 ...
1,多态是一种运行期绑定机制,通过这种机制,实现将函数名绑定到函数具体实现代码的目的.一个函数的名称与其入口地址是紧密相连的,入口地址是该函数在内存中的起始地址.如果对一个函数的绑定发生在运行时刻而非 ...
1, class 和 struct 都可以定义一个类,区别是两者在所支持的 默认信息隐藏方式不同:c++ 中默认为 private 类型,而 struct 中默认为 public 类型. 2,类的私有 ...
- 用大白话聊聊JavaSE -- 如何理解Java Bean(一)
首先,在开始本章之前,先说一个总的概念:所谓的Java Bean,就是一个java类,编译后成为了一个后缀名是 .class的文件.这就是Java Bean,很多初学者,包括当年的我自己,总是被这些专 ...
- OpenModelica仿真
复杂产品通常涉及机械.控制.电子.液压.气动和软件等多学科领域,其设计过程需要进行仿真,以满足对成本.质量.性能等的要求.目前各个学科和领域都已经有了比较成熟的仿真软件,但大部分仿真软件仅适用于本学科 ...
- 微信小视频复制到手机本地Android APP 分享
因为需要将拍的宝宝的微信小视频上传到亲宝宝软件,每次去手动找文件比较麻烦,所以做了个微信视频复制到手机本地的APP,做工虽然粗糙,但是绝对实用, 下载地址 http://pan.baidu.com/s ...
- 4..一起来学hibernate之Session详解
后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续... 后续...
- [团队项目]SCRUM项目6.0 7.0 (新)
6.0----------------------------------------------------- sprint演示 1.坚持所有的sprint都结束于演示. 团队的成果得到认可,会感觉 ...
- 【总结】Java线程同步机制深刻阐述
原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...
- display: inline-block 的神奇效果
先上要实现的效果图: 方案一:来自卢兄: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 通用的星星类已经完成了,下面我们来实现具体的变长和缩短道具. 变 ...
- java面试题复习(六)
51.实现多线程的方法 一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如 ...
- 《A_Pancers》第一次作业:团队亮相
一.团队及团队成员介绍 1> 队名:A_Pancers 2> 团队成员组成: 201571030310/龙正圆(小组长) 201571030329/杨环宇 20157103030 ...








