从另一个线程向 QSerialPort 发送数据

Posted

技术标签:

【中文标题】从另一个线程向 QSerialPort 发送数据【英文标题】:Sending data to QSerialPort from another thread 【发布时间】:2016-03-02 15:13:40 【问题描述】:

我正在尝试使用 QSerialPort 类通过串行端口发送一些数据。每次都从同一个父类发送数据效果很好。但是当我尝试使用另一个线程 QSerialPort 发送数据时,它不会。我用串口监视器观察数据,它什么也没显示。 代码如下:

#include <QSerialPort>
#include <QObject>
#include <QDebug>
#include <QCoreApplication>

#include <thread>
#include <mutex>
#include <list>
#include <memory>

class Message 
public:
    bool isSent;
    bool isProcessed;
    int data;

    Message(int d) :
        data(d),
        isSent(false),
        isProcessed(false) 

    
;

class SerialClass : public QObject 
    Q_OBJECT

public:
    SerialClass(unsigned short portNumber, unsigned int baudrate, QObject *parent = 0) :
        _portNumber(portNumber),
        _baudrate(baudrate),
        _serialPort(new QSerialPort(this)),
        _messages(),
        _writeThread(nullptr),
        QObject(parent) 

        _serialPort->setPortName(QString("COM%1").arg(_portNumber));
        _serialPort->setBaudRate(baudrate);
        _serialPort->setDataBits(QSerialPort::DataBits::Data8);
        _serialPort->setParity(QSerialPort::Parity::NoParity);
        _serialPort->setStopBits(QSerialPort::StopBits::OneStop);
    


    void start() 

        if (!_serialPort->open(QIODevice::ReadWrite)) 
            qDebug() << "Couldn't open serial port";
            return;
        

        auto *m = &_messages;
        auto *p = &_enableProcessing;
        auto *port = _serialPort.get();
        auto *mutex = &_mutex;

        _serialPort->write(QString("Hello\r\n").toLocal8Bit());

        _writeThread = std::make_unique<std::thread>([m, p, port, mutex]() 
            qDebug() << "Work thread started";
            while (*p) 
                std::this_thread::sleep_for(std::chrono::milliseconds(15));
                auto inactiveMessage = std::find_if(m->begin(), m->end(), [](Message &item) 
                    return !item.isSent;
                );

                if (inactiveMessage != m->end()) 
                    mutex->lock();
                    qDebug() << "Written" << port->write(QString("data %1\r\n").arg(inactiveMessage->data).toLocal8Bit());
                    inactiveMessage->isSent = true;
                    mutex->unlock();
                
            
            qDebug() << "Work thread stopped";
        ); 
    

    void wait() 
        if (!_writeThread) 
            return;
        
        _writeThread->join();
    


    void addMessage(Message& msg) 
        _mutex.lock();
        _messages.push_back(msg);
        _mutex.unlock();
    

private:
    unsigned short _portNumber;
    unsigned int _baudrate;
    std::unique_ptr<QSerialPort> _serialPort;
    std::unique_ptr<std::thread> _writeThread;
    std::list<Message> _messages;
    bool _enableProcessing;
    std::mutex _mutex;
;


int main(int argc, char ** argv) 
    QCoreApplication application(argc, argv);
    SerialClass serialProcessor(2, 9600, &application);

    serialProcessor.addMessage(Message(228));
    serialProcessor.addMessage(Message(929));
    serialProcessor.addMessage(Message(221424));

    serialProcessor.start();

    return application.exec();


#include "main.moc"

这是否意味着 QSerialPort 类不能从另一个线程传输数据? (不是 QSerialPort 线程)

【问题讨论】:

QObject 派生类只能与在QThread 中运行的事件循环一起使用。值得庆幸的是,QThread 的默认 run() 实现已经为您旋转了一个事件循环。 【参考方案1】:
    建议不要在同一个项目中混合使用 STL 和 Qt 解决方案 QSerialPort 可以在任何线程中工作 您可以在此处查看正确使用QThread 的示例:https://***.com/a/35673612/4149835

【讨论】:

以上是关于从另一个线程向 QSerialPort 发送数据的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法从另一个进程向线程发送信号?

读写串口 类QSerialPort

多线程代码中 QSerialPort 的 Qt 错误:QCoreApplication::sendEvent:“无法将事件发送到不同线程拥有的对象

Python Tornado 从另一个线程发送 WebSocket 消息

使用 QSerialPort 通过串口发送数据

Android:子线程向UI主线程发送消息