#QT 串口信息一次读取不全的问题【简易解决方案】
问题A描述:向该设备A每次发送一次数据后,就立刻从串口读取设备A的返回数据,串口每次返回的信息不多,但是每次QT 自身的串口 readyread()函数后readAll()串口数据总是不全,于是找了各种方案(网上主要集中于
1.加一个计时器timer每秒读取一次,然后将数据累加
2.serial->waitForReadyRead(1000)增加延时的方式,但是依然不能解决我的问题)。
最后,发现采用更简单的一次延时任务的方案即可。
解决方案:即在第一次触发了waitForReadyRead(),并readAll()一次以后,延时几毫秒再次readAll()即可读取剩余部分数据,简单又方便。
if(serial->waitForReadyRead(1000)) //等待数据返回(在1s内有消息触发则if为返回是,1s后则返回为否)
{
QByteArray str((serial->readAll()));
// qDebug() << "返回1 Bytearray: " << str;
data = ByteArrayToHexString(str);
}
else{
qDebug()<<"第一次ReadyRead未读取到数据";
}
//执行一次定时任务,1是指延时1ms
QTimer::singleShot(1, this, [=](){
QByteArray str2((serial->readAll()));
if(!str2.isEmpty()) //等待数据返回
{
qDebug() << "返回2 Bytearray: " << str2;
data2 = ByteArrayToHexString(str2);
qDebug() << "共返回 info: " << data+ByteArrayToHexString(str2);
}
else{
qDebug()<<"延时仍未读取到数据";
}
});
}
同理,该方式和思想也同样适用于我的另外一个问题。
问题B描述:设备B负责扫码,当扫到二维码数据时,会在约20ms内多次触发readyread()函数(有时也只触发一次,返回次数很随机),需要对几次触发的数据进行累加。
解决方案:
.h文件中命名变量,并初始化
QDateTime receiveTime;
bool firstTime=true;
QByteArray m_readData;
.cpp文件中先将readyRead与与槽函数readyReadSlot连接
connect(serial, &QSerialPort::readyRead, this, &SerialQrcode::readyReadSlot);
实现一次二维码读取,延时返回数据(中间多次readyRead触发被append累加)
void SerialQr::readyReadSlot()
{
m_readData.append(serial->readAll());
//如果是第一次触发readyread,则触发一个延时任务,x时间后向主线程发送结果数据,在x时间内自动累加append数据(解决每次刷码时,readyread多次触发的问题)
if(firstTime){
receiveTime= QDateTime::currentDateTime();
qDebug() <<"这是第一次触发哦"<<receiveTime;
firstTime = false;
QTimer::singleShot(100, this, [=](){//参数100可以根据实际情况进行调整
qDebug() <<serial->portName()<< "二维码数据:"<<m_readData;
emit receive_qrcode_data(QString(m_readData));//发出信号,将数据传至主线程
m_readData.clear();
firstTime = true;
});
}else{
qDebug() <<"这不是首次触发哦,与首次的间隔为"<<receiveTime.msecsTo(QDateTime::currentDateTime())<<"ms";
}
}