【问题标题】:Sending data to QSerialPort from another thread从另一个线程向 QSerialPort 发送数据
【发布时间】: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() 实现已经为您旋转了一个事件循环。

标签: c++ multithreading qt


【解决方案1】:
  1. 建议不要在同一个项目中混合使用 STL 和 Qt 解决方案
  2. QSerialPort 可以在任何线程中工作
  3. 您可以在此处查看正确使用QThread 的示例:https://stackoverflow.com/a/35673612/4149835

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    相关资源
    最近更新 更多