yanwuyue的个人主页

http://www.qtcn.org/bbs/u/155383  [收藏] [复制]

yanwuyue

  • 15

    关注

  • 22

    粉丝

  • 75

    访客

  • 等级:侠客
  • 总积分:212
  • 男,1989-04-20

最后登录:2024-04-08

更多资料

日志

线程安全串口类

2015-07-28 11:16
工作需要串口在不同线程中调用,直接调用QSerialPort程序甚至会冲突而崩溃,
原理是将串口直接挂在一个线程里面,采用信号通讯
  1. #ifndef TCOM_H
    #define TCOM_H
    #include <QObject>
    #include "ComParam.h"//定义了[backcolor=#f7f7f7][color=#000000]ComPD你可以自己改[/color][/backcolor]
    class QSerialPort;
    class TCom : public QObject
    {
        Q_OBJECT
    public:
        explicit TCom(const ComPD *param,QObject *parent = 0);
        QByteArray data;
        bool isOpen;
    private:
        QSerialPort *com;
        const ComPD *p;
    signals:
        void dllMessage(int id,int error,const QString& message="");
    public slots:
        void run();
        void clear();
        void write(const QByteArray &data);
    private slots:
        bool comOpen();
        void readyRead();
    };
    #endif // TCOM_H

  1. #include "tcom.h"
    #include <QSerialPort>
    #include <QThread>
    TCom::TCom(const ComPD *param, QObject *parent) :
        QObject(parent),
        com(NULL),
        p(param),
        isOpen(false)
    {
        //time.start();
    }
    bool TCom::comOpen()
    {
        if(!com->open(QIODevice::ReadWrite))
        {
            delete com;
            com=NULL;
            dllMessage(5,-2,tr("打开串口(%1)失败").arg(p->port));
            return false;
        }
        com->setBaudRate(p->baud);
        com->setDataBits(QSerialPort::Data8);
        com->setParity(QSerialPort::NoParity);
        com->setStopBits(QSerialPort::OneStop);
        com->setFlowControl(QSerialPort::NoFlowControl);
        com->setReadBufferSize(1024);
        return true;
    }
    void TCom::run()
    {
        com=new QSerialPort(p->port,this);
        if(!comOpen())
        {
            delete com;
            com=NULL;
            return;
        }
        connect(com,SIGNAL(readyRead()),this,SLOT(readyRead()));
        isOpen=true;
    }
    void TCom::readyRead()
    {
        data+=com->readAll();
    #ifdef QT_DEBUG
        qDebug()<<"m8_read:"<<this->thread()<<data;
    #endif
    }
    void TCom::clear()
    {
        com->clear();
    }
    void TCom::write(const QByteArray &data)
    {
    //#ifdef QT_DEBUG
    //    qDebug()<<"write:"<<this->thread();
    //#endif
        clear();
        com->write(data);
    }



  1. bool yourClass::open(const ComPD *p)
    {
        if(p->port.size()<4 || p->baud<=0)
        {
            dllMessage(5,-2,tr("缺少串口参数:%1").arg("xxxxxx"));
            return false;
        }
        if(com!=NULL)
        {
            return false;
        }
        com=new TCom(p);
        thread_com=new QThread;
        com->moveToThread(thread_com);
        connect(thread_com,SIGNAL(started()),com,SLOT(run()));
    [color=#008ef1]     //这个必须加,直接emit [/color]com->write(),不会跨线程
        connect(this,SIGNAL(write(QByteArray)),com,SLOT(write(QByteArray)));
        thread_com->start();
        while (!com->isOpen)
        {
            this->thread()->msleep(1);
        }
        return true;
    }




分类:Qt5|回复:2|浏览:1385|全站可见|转载
 

下一篇: Sqlite中括号的意义

上一篇:

 
删除

realfan:run里面,不加exec(),线程瞬间就结束了

2015-07-31 09:46 -

yanwuyue:不要用exec();thread_com全局的,你不结束它,它怎么会关闭呢

2015-07-31 21:41

Powered by phpwind v8.7 Certificate Copyright Time now is:04-28 03:26
©2005-2016 QTCN开发网 版权所有 Gzip disabled