Создать QIODevice (QSerialPort) в отдельном потоке

148
19 февраля 2021, 00:20

Класс QSerialPort, насколько я понимаю, не предназначен для работы с QThread. Поэтому делаю класс наследник который сможет работать с QThread, в котором добавляю недостающие сигналы и слоты. И хочу узнать все ли я сделал правильно, все ли должно работать? нет ли в коде "велосипедов"? Обязателен ли m_loop?

serialportthread.h

#ifndef MYSERIALPORT_H
#define MYSERIALPORT_H
#include <QEventLoop>
#include <QSerialPort>
class SerialPortThread : public QSerialPort
{
    Q_OBJECT
    QEventLoop m_loop;  // for thread run
public:
    struct Settings {
        QString name;
        qint32 baudRate;
        QString stringBaudRate;
        QSerialPort::DataBits dataBits;
        QString stringDataBits;
        QSerialPort::Parity parity;
        QString stringParity;
        QSerialPort::StopBits stopBits;
        QString stringStopBits;
        QSerialPort::FlowControl flowControl;
        QString stringFlowControl;
    };
    SerialPortThread(Settings s, QObject *parent = nullptr);
public slots:
    void start();
    void stop();
    void txMsg(QByteArray txMsg);
signals:
    void stoped(int status);
    void started();
    void rxMsg(QByteArray rxMsg);
};
#endif // MYSERIALPORT_H

serialportthread.cpp

#include "serialportthread.h"
SerialPortThread::SerialPortThread(Settings s, QObject *parent)
    : QSerialPort(s.name, parent)
{
    setBaudRate(s.baudRate);
    setDataBits(s.dataBits);
    setParity(s.parity);
    setStopBits(s.stopBits);
    setFlowControl(s.flowControl);
    connect(this, &QSerialPort::readyRead, [this] {
        auto msg = readAll();
        emit rxMsg(msg);
    });
    connect(this, &SerialPortThread::stoped, [this] () { m_loop.exit(); });
}
void SerialPortThread::start()
{
    if (!open(QIODevice::ReadWrite)) {
        emit stoped(1); // error
        return;
    }
    emit started();
    m_loop.exec();
}
void SerialPortThread::stop()
{
    if (isOpen()) {
        close();
    }
    m_loop.exit();
    emit stoped(0);
}
void SerialPortThread::txMsg(QByteArray txMsg)
{
    write(txMsg);
}

И примерный код для контроллеров потока:

void ControllerThreads::openDevice(SerialPortThread::Settings settings)
{
    SerialPortThread *comPort = new SerialPortThread(settings);
    QThread* thread = new QThread;
    comPort->moveToThread(thread);
    connect(thread, &QThread::started, comPort, &SerialPortThread::start);
    connect(comPort, &SerialPortThread::rxMsg, this, &ControllerThreads::rxDevice);
    connect(comPort, &SerialPortThread::stoped,
            [=] (int i) { qDebug() << "finished:" << i; });
    connect(comPort, &SerialPortThread::stoped,
            comPort, &SerialPortThread::deleteLater);
    connect(thread, &QThread::finished, comPort, &SerialPortThread::deleteLater);
    connect(thread, &QThread::finished, thread, &QThread::deleteLater);
    thread->start();
}
READ ALSO
map перезаписывает элемент а не добавляет

map перезаписывает элемент а не добавляет

Метод map перезаписывает элемент а не добавляет новый, пробовал и методом emplace и pair, в чем ошибка подскажите?

114
Как работает istream&amp; параметр?

Как работает istream& параметр?

Помогите разобраться нубу с тем, как работает istream&, конкретно интересует следующая конструкция:

115
Как присвоить wchar[256] переменную?

Как присвоить wchar[256] переменную?

Есть текстовый файл в котором хранится ссылка к примеру (https://rustackoverflow

118