我从串口读取的数据(在Qt中,使用QtSerialPort / QSerialPort)由换行符'\ n'分隔并返回'\ r'字符,这是我打算查看它以进行解析的方式。行长可能很长,但很容易从每行的格式中提取数据。
//signal/slot connection on readyRead() is as follows:
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
其中readData()定义为:
void MainWindow::readData()
{
//As mentioned below, which I will reiterate, I have already tried the addition of
// canReadLine():
if (serial->canReadLine()){
QByteArray data = serial->readLine();
//QByteArray allData = serial->readAll();
parseSerialBytes(data);
//console->putData(data);
//console->putData(alldata);
}
}
然而,与{QIODevice :: readAll()相比,QIODevice::readLine()
函数非常慢,并且明显阻止数据以全频率接收
有人可以解释一下如何正确使用readLine()
函数,这样我就不必通过readAll()
遍历QByteArray
来解析每一行吗?我使用“终端”Qt Widgets示例来创建此异步串行端口读取功能。
提前致谢 - 这似乎是我在这里尚未见到的常见问题。
答案 0 :(得分:5)
这是常见错误。 readData
每个数据块只被调用一次,不一定每行一次。
只要数据可用,您就需要继续阅读。在widget类中进行串行读取也是一种糟糕的设计。将其移动到单独的对象。
class Receiver : public QObject {
Q_OBJECT
QSerialPort m_port;
QByteArray m_buffer;
void processLine(const QByteArray & line) {
...
}
Q_SLOT void readData() {
// IMPORTANT: That's a *while*, not an *if*!
while (m_port.canReadLine()) processLine(m_port.readLine());
}
public:
Receiver(QObject * receiver = 0) : QObject(parent) {
connect(&m_port, &QIODevice::readyRead, this, &Receiver::readData);
...
}
}
您的错误是实施readData
,如下所示。无论有多少行可供读取,此类代码只读取一行。它会出现'慢慢'#34;因为在每次调用时,越来越多的累积数据留下未读。最终,它将耗尽堆。
void readData() {
// WRONG!
if (m_port.canReadLine()) processLine(m_port.readLine());
}