qt一个在线程管理的串口

 

#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QThread>
#include <QTimer>
#include <QEventLoop>

class SerialPortController : public QSerialPort
{
    Q_OBJECT
public:
    explicit SerialPortController(QObject* parent = nullptr)
        :QSerialPort(parent)
    {
        connect(this,&SerialPortController::signal_SendData,this,&SerialPortController::OnSendData);
        connect(this, &SerialPortController::readyRead, this, &SerialPortController::OnReadyRead,Qt::DirectConnection);
    }
    ~SerialPortController(){}
signals:
    void signal_SendData(const QByteArray &d);
    void signal_ReadData(const QByteArray &d);
public slots:
    void OnSendData(const QByteArray &d) {
        qint64 len = write(d);
    }
    void OnReadyRead()
    {
        QByteArray d = readAll();
        if(d.length()>0)
        {
            emit signal_ReadData(d);
        }
    }
};

/*
使用方式:
SerialPortEx 创建一个对象
  open((QString port, int baud,int Flow。。。)打开串口
WriteData(QByteArray d)发送数据
signal_ReadData(const QByteArray&) 信号曹返回tcp数据
****************************/

class SerialPortEx : public QObject
{
    Q_OBJECT
public:
    explicit SerialPortEx(QObject* parent = nullptr)
        :QObject(parent)
    {
        serial = new SerialPortController;

        connect(serial, &SerialPortController::errorOccurred, [=](QSerialPort::SerialPortError error)
                {
                    if (error != QSerialPort::NoError  ) {
                        emit signal_ConnectStatus(false);
                        connect_flag = false;
                        qDebug()<<port_name<<"error"<< error;
                    }
                });
    }
    ~SerialPortEx()
    {
        workerThread.quit();
        workerThread.wait();
    }

    // port;//串口号
    // baud;//波特率
    // Flow =流控制:无控制,硬件控制,软件控制等
    // parity;//校验位
    // dataBits;//数据位
    // stopBits;//停止位
    bool open(QString port, int baud,int Flow = QSerialPort::NoFlowControl, QString dataBits = "8", QString stopBits = "1", QString parity = "0")
    {
        try
        {
            port_name= port;
            serial->setPortName(port_name);
            if (serial->isOpen()) {
                serial->close();
            }
            if (serial->open(QIODevice::ReadWrite))
            {
                serial->flush(); //清空缓冲区
                serial->setBaudRate((QSerialPort::BaudRate)baud); //设置波特率
                serial->setDataBits((QSerialPort::DataBits)dataBits.toInt()); //设置数据位
                serial->setParity((QSerialPort::Parity)parity.toInt()); //设置校验位
                serial->setStopBits((QSerialPort::StopBits)stopBits.toInt()); //设置停止位
                serial->setFlowControl((QSerialPort::FlowControl)Flow);//Hardware flow control (RTS/CTS)
                //connect(serial, &QSerialPort::readyRead, this, &SerialPortEx::readyReadSlot,Qt::QueuedConnection);
                connect_flag = true;

                serial->moveToThread(&workerThread);
                connect(&workerThread, &QThread::finished, serial, &QObject::deleteLater);
                connect(serial, &SerialPortController::signal_ReadData, this, &SerialPortEx::signal_ReadData);
                workerThread.start();
                emit signal_ConnectStatus(true);

                return true;
            }

        }
        catch (...)
        {
            qCritical()<<"打开串口失败"<<port << ":" << baud;
        }
        return false;
    }
    void close()
    {
         serial->close();
    }

    void WriteData(QByteArray d)
    {
        if(!connect_flag)return;
        emit serial->signal_SendData(d);
    }
    void WriteData(QString val)
    {
        WriteData(val.toLatin1());
    }

    bool getConSts()
    {
        return connect_flag;
    }

    void waitReady(int time)
    {
        if(!connect_flag)return;

        if(time < 0)
        {
            qCritical()<<"SerialPortEx waitReady error msec "<<time;
        }
        QEventLoop Loop;
        QTimer::singleShot(time, &Loop, SLOT(quit()));
        Loop.exec();
    }

private:
    SerialPortController* serial;

    QString port_name ;
    bool connect_flag = false;

     QThread workerThread;

signals:
    void signal_ReadData(const QByteArray &d);
    void signal_ConnectStatus(bool status);
};

 

posted on 2024-05-25 11:41  七星落地  阅读(126)  评论(0)    收藏  举报