Что ж, с вашего позволения, устрою небольшое code review.
Установка параметров порта.
Да, метод setPortName не возвращает ничего. Но, вызовы
QSerialPort::setBaudRate,
QSerialPort::setDataBits,
QSerialPort::setParity,
QSerialPort::setStopBits и
QSerialPort::setFlowControl могут вернуть
false. Пытаться открыть после этого порт явно не стоит. Лучше вызвать
QSerialPort:error, чтобы обработать ошибку.
Сигналы и слоты.
- Cоединить сигнал QSerialPort::readyRead со слотом ComPort::HandleReadyRead можно сразу после создания экземпляра QSerialPort. До установки параметров порта и его открытия.
- Однозначно, необходимо подключить сигнал QSerialPort::errorOccurred и реализовать обработку ошибок. Ну хотя бы их вывод в консоль во время отладки.
- Пожалуйста, не используйте макросы SIGNAL и SLOT. Переходите на функторы.
QObject::connect (com_port_, &QSerialPort::readyRead, this, &ComPort::handleReadyRead);
QObject::connect (com_port_, &QSerialPort::errorOccurred, this, &ComPort::handleError);
Открытие порта.
Метод
QSerialPort::open следует вызывать только
после успешной установки параметров порта (см. выше). И даже после этого он может вернуть
false. В этом случае ничего не остаётся, как вызвать
QSerialPort:error, чтобы отреагировать на ошибку. Кстати, это рекомендации из официальной документации.
Чтение данных.
Во-первых, метод чтения данных
QSerialPort::read может вернуть -1 в случае ошибки. А метод
QSerialPort::readAll в случае ошибки вернёт пустой QByteArray. Что нужно делать в этом случае? Правильно! Вызвать
QSerialPort:error, чтобы отреагировать на ошибку.
Во-вторых, я бы не стал полагаться на каждое срабатывание сигнала
QSerialPort::readyRead, а использовал бы цикл с методом
QIODevice::bytesAvailable, в котором считываются и обрабатываются все данные, о приходе которых стало известно по упомянутому выше сигналу.
void ComPort::HandleReadyRead()
{
while (serial_->bytesAvailable () > 0) {
// Чтение данных
QByteArray data = serial_->readAll ();
if (data.isEmpty ()) {
handleError ();
return;
}
read_buffer_.append (data);
// Здесь ещё пристуствует логика обработки сообщения, я ищу символ конца
// сообщения, и если его нахожу, то эмитирую сигнал, для вызова слота парсинга сообщения.
}
}
В-третьих, на момент закрытия порта он может располагать данными, которые вы не успели прочитать. Для обработки этой ситуации, метод чтения данных следует вызвать перед закрытием порта. Возможно, это не ваш случай. Но, на моей практике он бывал много раз.
Обработка ошибок.
Простите, но у вас она отсутствует как класс. Реализуйте, например, предлагаемый мною ComPort::handleError.
void ComPort::handleError (QSerialPort::SerialPortError error)
{
qDebug () << __LINE__ << __FUNCTION__ << error;
}
Заключение.
На мой взгляд, только после указанных выше доработок можно приступить к рассмотрению вопроса по существу. И вообще хоть как-то локализовать проблему.