Qserialport readLine () чрезвычайно медленный по сравнению с readAll()

данные, которые я читаю из serialport (в Qt, используя QtSerialPort/QSerialPort), разделены символами новой строки 'n' и return '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);
   }
}
на

1 ответов


это общая ошибка. The readData вызывается только один раз на кусок данных не обязательно раз в строке.

вам нужно продолжать читать строки до тех пор, пока данные доступны. Это также плохой дизайн, чтобы иметь последовательное чтение строки в классе виджетов. Переместите его в отдельный объект.

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 как показано ниже. Этот код считывает только одну строку независимо от того, сколько линий имеется считывать. Он будет казаться "медленным", так как при каждом вызове появляется все больше и больше накопленных данных, которые остаются непрочитанными. В конце концов, все закончится.

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