<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_OBJECT public:
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,类的私有 ...
随机推荐
- 完毕乔布斯的梦想:一个免费wifi共享的乌托邦
早在2007年推出iPhone时,乔布斯就提出这种如果:商业区与居民区的wifi路由器全民开放,实现与路人共享网络之便.能够想象,那算是一个wifi共享的乌托邦. 数年过去了,乔布斯的梦想依然没能全然 ...
- hdoj-1212-Big Number【大数取余&简单题】
Big Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- Android里使用正則表達式
在Android里怎样使用正則表達式: 以验证username为例.username一般字母开头,同意字母数字下划线.5-16个字节: String regEx = "^[a-zA-Z][a ...
- SpringMVC案例3----spring3.0项目拦截器、ajax、文件上传应用
依然是项目结构图和所需jar包图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmVuamFtaW5fd2h4/font/5a6L5L2T/fontsi ...
- 上传canvas图片到服务器
canvas绘图后用 canvasDom.toDataURL()可以得到png格式图片的base64 dataURI 然后用ajax post给后台 ,后端程序把开头的data:image/png; ...
- C内存管理一 概述
我们写了这么多年的程序猿.可能理论方面还比不上大学生.有人 "嘘"我了,假设有能回答下面几个问题的同学请举手: 1.面试常常遇到:同学请说说堆栈的差别? 2.同学请说说一个函数在堆 ...
- UI组件之AdapterView及其子类(四)Gallery画廊控件使用
听说 Gallery如今已经不使用了,API使用ViewPaper取代了,以后再学专研ViewPaper吧如今说说Gallery画廊,就是不停显示图片的意思 Gallery是用来水平滚动的显示一系列项 ...
- nj08---process、console
概念:所有属性都可以在程序的任何地方访问,即全局变量.在JavaScript中,通常window是全局对象,而Node.js的全局对象是global,所有全局变量都是global对象的属性,如:con ...
- WinRar 设置默认的压缩格式为zip
By default, WinRar uses the RAR archive format for compressing files. You may prefer using the more ...
- hdoj--1237--简单计算器(栈模拟)
简单计算器 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...