QSerialPort readLine()与readAll()相比非常慢, [英] QSerialPort readLine() extremely slow compared to readAll()

查看:4954
本文介绍了QSerialPort readLine()与readAll()相比非常慢,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从串口中读取的数据(在Qt中,使用QtSerialPort / QSerialPort)由换行符'\\\
'和返回'\r'字符分隔,这是我打算查看它的方式用于解析。行长度可以很大,但很容易从每行的格式中提取数据。

The data I'm reading from a serialport (in Qt, using QtSerialPort/QSerialPort) is separated by the newline '\n' and return '\r' characters, which is the way I intend to look at it for parsing. The line length may very, but it is very easy to extract the data from the format of each line.

//signal/slot connection on readyRead() is as follows:
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

其中readData()定义为:

where readData() is defined as:

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);
   }
}

:readLine()函数非常慢,并且清楚地阻止以全频率接收数据与QIODevice :: readAll()相比

However, the QIODevice::readLine() function is extremely slow, and clearly blocking data from being received at full frequency compared to QIODevice::readAll()

有人可以解释如何正确使用 readLine()函数,所以我不必循环通过 readAll QByteArray 中来解析每一行?我使用终端Qt Widgets示例来创建这个异步串口读取功能。

Can someone please explain how to properly use the readLine() function so I don't have to loop through readAll() into the QByteArray to parse each line? I used the "terminal" Qt Widgets example to create this asynchronous serialport read functionality.

提前感谢 - 这似乎是我尚未看到的常见问题。

Thanks in advance - this seems to be a common problem I have not yet seen answered here.

推荐答案

这是一个常见错误。 readData 仅对每个数据块调用一次,不一定每行一次。

This is a common error. The readData is called only once per a chunk of data, not necessarily once per line.

只要数据可用,您就需要继续阅读行。在widget类中有串行线读取也是一个糟糕的设计。将其移动到单独的对象。

You need to keep reading lines as long as data is available. It is also a bad design to have serial line reading in a widget class. Move it to a separate object.

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 ,如下所示。这样的代码只读取一行,不管有多少行可用于读取。它会出现慢,因为每次调用有越来越多的积累数据留下未读。最终,它将用完堆。

Your error was to implement readData as shown below. Such code reads only one line no matter how many lines are available to be read. It'll appear "slow" since on each invocation there's more and more accumulated data that's left behind unread. Eventually it'll run out of heap.

void readData() {
  // WRONG!
  if (m_port.canReadLine()) processLine(m_port.readLine());
}

这篇关于QSerialPort readLine()与readAll()相比非常慢,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆