有时候经常需要把串口放到单独的一个线程去处理数据,于是我就把串口封装了一下,即支持了多线程也方便使用。
特性介绍:
1.串口工作是在一个单独的线程,更加稳定
2.实例化的对象可在多个线程被调用且不会出错
注意:
1.一些control开头的信号,是内部通讯用的,请勿直接使用
2.一般来说,只要管accepted和error两个信号就可以了
3.JasonQt_SerialPort_Run这个是工作用的类,不推荐直接使用
4.用到了C++11语法,所以请务必开启11模式,不然会编译报错
5.我使用的是Qt5.4.0,理论上5.2开始都可以用这份源码
6.使用前请在pro文件中加入
QT += serialport
CONFIG += c++11
不多说,上源码。
JasonQt_SerialPort.h
#ifndef __JasonQt_Serialport_h__
#define __JasonQt_Serialport_h__
// Qt lib import
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QThread>
#include <QEventLoop>
class JasonQt_SerialPort;
class JasonQt_SerialPort_run: public QObject
{
Q_OBJECT
private:
JasonQt_SerialPort *m_parent = NULL;
QSerialPort *m_serialPort = NULL;
public:
JasonQt_SerialPort_run(JasonQt_SerialPort *parent);
public slots:
void open(const QString &portName, const int &baudRate, const QSerialPort::DataBits &dataBits, const QSerialPort::Parity &parity, const QSerialPort::StopBits &stopBits);
void close(void);
void send(const QByteArray &data);
private slots:
void accepted(void);
void error(const QSerialPort::SerialPortError &error);
signals:
void controlOpened(const bool isOpen);
};
class JasonQt_SerialPort: public QThread
{
Q_OBJECT
private:
JasonQt_SerialPort_run *m_serialPort = NULL;
public:
JasonQt_SerialPort(void);
~JasonQt_SerialPort(void);
public slots:
bool open(const QString &portName, const int &baudRate,
const QSerialPort::DataBits &dataBits = QSerialPort::Data8,
const QSerialPort::Parity &parity = QSerialPort::NoParity,
const QSerialPort::StopBits &stopBits = QSerialPort::OneStop);
void close(void);
void send(const QByteArray &data);
private:
void run(void);
signals:
void accepted(const QByteArray data);
void error(const QSerialPort::SerialPortError error);
void controlOpen(const QString portName, const int baudRate, const QSerialPort::DataBits dataBits, const QSerialPort::Parity parity, QSerialPort::StopBits stopBits);
void controlClose(void);
void controlSend(const QByteArray data);
};
#endif//__JasonQt_Serialport_h__
JasonQt_SerialPort.cpp
#include "JasonQt_SerialPort.h"
// JasonQt_SerialPort_run
JasonQt_SerialPort_run::JasonQt_SerialPort_run(JasonQt_SerialPort *parent)
{
m_parent = parent;
m_serialPort = NULL;
}
void JasonQt_SerialPort_run::open(const QString &portName, const int &baudRate, const QSerialPort::DataBits &dataBits, const QSerialPort::Parity &parity, const QSerialPort::StopBits &stopBits)
{
if(m_serialPort)
{
this->close();
}
m_serialPort = new QSerialPort(portName);
#ifndef Q_OS_WIN
m_serialPort->setBaudRate(baudRate);
m_serialPort->setDataBits(dataBits);
m_serialPort->setParity(parity);
m_serialPort->setStopBits(stopBits);
#endif
connect(m_serialPort, SIGNAL(readyRead()), this, SLOT(accepted()), Qt::DirectConnection);
connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(error(QSerialPort::SerialPortError)), Qt::DirectConnection);
if(!m_serialPort->open(QIODevice::ReadWrite))
{
emit controlOpened(false);
return;
}
#ifdef Q_OS_WIN
m_serialPort->setBaudRate(baudRate);
m_serialPort->setDataBits(dataBits);
m_serialPort->setParity(parity);
m_serialPort->setStopBits(stopBits);
#endif
emit controlOpened(true);
}
void JasonQt_SerialPort_run::close(void)
{
if(m_serialPort)
{
m_serialPort->close();
m_serialPort->deleteLater();
m_serialPort = NULL;
}
}
void JasonQt_SerialPort_run::send(const QByteArray &data)
{
if(m_serialPort)
{
m_serialPort->write(data);
}
}
void JasonQt_SerialPort_run::accepted(void)
{
if(m_serialPort)
{
emit m_parent->accepted(m_serialPort->readAll());
}
}
void JasonQt_SerialPort_run::error(const QSerialPort::SerialPortError &error)
{
if(error)
{
emit m_parent->error(error);
}
}
// JasonQt_SerialPort
JasonQt_SerialPort::JasonQt_SerialPort(void)
{
static bool flag = true;
if(flag)
{
flag = false;
qRegisterMetaType<QSerialPort::DataBits>("QSerialPort::DataBits");
qRegisterMetaType<QSerialPort::Parity>("QSerialPort::Parity");
qRegisterMetaType<QSerialPort::StopBits>("QSerialPort::StopBits");
qRegisterMetaType<QSerialPort::SerialPortError>("QSerialPort::SerialPortError");
}
this->start();
}
JasonQt_SerialPort::~JasonQt_SerialPort(void)
{
this->quit();
this->wait();
}
bool JasonQt_SerialPort::open(const QString &portName, const int &baudRate,
const QSerialPort::DataBits &dataBits,
const QSerialPort::Parity &parity,
const QSerialPort::StopBits &stopBits)
{
QEventLoop eventLoop;
bool flag = false;
auto a = connect(m_serialPort, SIGNAL(controlOpened(bool)), &eventLoop, SLOT(quit()), Qt::DirectConnection);
auto b = connect(m_serialPort, &JasonQt_SerialPort_run::controlOpened, [&](const bool &isOpen){ flag = isOpen; });
emit controlOpen(portName, baudRate, dataBits, parity, stopBits);
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
disconnect(a);
disconnect(b);
return flag;
}
void JasonQt_SerialPort::close(void)
{
emit controlClose();
}
void JasonQt_SerialPort::send(const QByteArray &data)
{
emit controlSend(data);
}
void JasonQt_SerialPort::run(void)
{
m_serialPort = new JasonQt_SerialPort_run(this);
connect(this, SIGNAL(controlOpen(QString,int,QSerialPort::DataBits,QSerialPort::Parity,QSerialPort::StopBits)),
m_serialPort, SLOT(open(QString,int,QSerialPort::DataBits,QSerialPort::Parity,QSerialPort::StopBits)));
connect(this, SIGNAL(controlClose()), m_serialPort, SLOT(close()));
connect(this, SIGNAL(controlSend(QByteArray)), m_serialPort, SLOT(send(QByteArray)));
this->exec();
delete m_serialPort;
m_serialPort = NULL;
}
使用效果
作者:wsj
你好 我是一个实习生,现在在做的就是一个关于串口通信的项目,我发现我现在的问题就是在主线程里面new了serialport然后在其他的线程使用,然后就报错了。能帮忙解决一下吗?