- Qt的串口类每次获取到电脑上存在的所有的串口都需要使用一下代码:
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //遍历所有可用串口
{
portNameList.push_back(info.portName());
}
void SerialPort::refreshSerialPort()
{
if(this->isOpen()){
this->close();
}
portNameList.clear();
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
portNameList.push_back(info.portName());
}
}
- readyRead()信号会在有数据时就触发,这时可能并没有接收到含有结尾标志位(“\r\n”等)的所有数据 。我对该部分做了封装
connect(this, &SerialPort::readyRead, this,[this]() {
this->dataReceived();
});
void SerialPort::dataReceived()
{
QByteArray data = this->readAll(); // 读取数据
if(!data.isEmpty()) // 接收到数据
{
QString str = std::move(readBuf); // 返回纯文本
str += tr(data); // 数据是一行一行传送的,要保存所有数据
int index = str.indexOf(endChar); // 找到,返回索引值,找不到,返回-1
if(index != -1)//接收到结尾标志符
{
readyData=std::move(str); // 将数据放入控件中
dataReady(); //数据已经准备好,发送信号
}else{
readBuf=std::move(str);
}
}
}
以下是源文件
serialport.h
#ifndef SERIALPORT_H
#define SERIALPORT_H
#include <QObject>
#include <QtSerialPort/QSerialPort> // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo> // 提供系统中存在的串口信息
class SerialPort: public QSerialPort
{
Q_OBJECT
public:
SerialPort(QSerialPort*parent=nullptr);
void refreshSerialPort(); // 刷新串口 //关闭当前打开的串口
bool setSerialPort(int index); //设置串口
void setEndMarker(QString endMarker); //设置以 "\r\n" "\r" "\n"等结尾
std::vector<QString> getPortNameList();
QString getData();
public slots:
// 串口槽函数
void dataReceived(); // 接收数据
// 串口槽函数
void dataSend(QString data); // 发送数据
signals:
void dataReady();
private:
std::vector<QString> portNameList; //当前存在的串口列表
int curPortIndex=0;
QString readyData; //接收到的准备好的数据,(已去掉结尾标识符)
QString readBuf; //未读取到结尾标识符的临时数据缓冲区
QString endMarker="\r\n";
};
#endif // SERIALPORT_H
serialport.cpp
#include "serialport.h"
SerialPort::SerialPort(QSerialPort*parent)
:QSerialPort(parent)
{
// 参数配置
// 波特率,波特率默认选择57600 ,禁止用户点击
this->setBaudRate(QSerialPort::Baud9600);
//ui->BaudBox->setDisabled(true);
// 校验,校验默认选择无
this->setParity(QSerialPort::NoParity);
// 数据位,数据位默认选择8位
this->setDataBits(QSerialPort::Data8);
// 停止位,停止位默认选择1位
this->setStopBits(QSerialPort::OneStop);
// 控制流,默认选择无
this->setFlowControl(QSerialPort::NoFlowControl);
// 刷新串口
refreshSerialPort();
connect(this, &SerialPort::readyRead, this,[this]() {
this->dataReceived();
});
}
// 刷新串口
void SerialPort::refreshSerialPort()
{
if(this->isOpen()){
this->close();
}
portNameList.clear();
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口
{
portNameList.push_back(info.portName());
}
}
bool SerialPort::setSerialPort(int index)
{
if(this->isOpen()){
this->close();
}
curPortIndex=index;
this->setPortName(this->portNameList[index]); //设置串口号
if (this->open(QIODevice::ReadWrite)){
//qDebug()<<"serial "<<this->portNameList[index]<<"open succcess"<<endl;
return true;
}
//qDebug()<<"serial "<<this->portNameList[index]<<"open faild"<<endl;
return false;
}
// 接收数据,使用read () / readLine () / readAll ()
void SerialPort::dataReceived()
{
QByteArray data = this->readAll(); // 读取数据
if(!data.isEmpty()) // 接收到数据
{
QString str = std::move(readBuf); // 返回纯文本
str += tr(data);
//qDebug() << "str info: " << str<<endl;
// 清除之前的数据,防止追加,因为每次获取的数据不一样
int index = str.indexOf(endMarker); // 找到,返回索引值,找不到,返回-1
if(index != -1)//接收到结尾标志符
{
readyData=std::move(str); // 将数据放入控件中
dataReady(); //数据已经准备好,发送信号
}else{
readBuf=std::move(str);
}
}
}
QString SerialPort::getData()
{
return this->readyData;
}
// 发送数据,write ()
void SerialPort::dataSend(QString data)
{
this->write(data.toLatin1()); // 串口发送数据
}
std::vector<QString> SerialPort::getPortNameList(){
return this->portNameList;
}
void SerialPort::setEndMarker(QString endMarker){ //设置以 "\r\n" "\r" "\n"等结尾
this->endMarker=endMarker;
}