Qt串口类QSerialPort的进一步封装

  • Qt的串口类每次获取到电脑上存在的所有的串口都需要使用一下代码:
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //遍历所有可用串口
    {
        portNameList.push_back(info.portName());
    }
  • 每次刷新操作可以重新读取当前可用的串口
void SerialPort::refreshSerialPort()
{
    if(this->isOpen()){
        this->close();
    }
    portNameList.clear();   
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) 
    {
        portNameList.push_back(info.portName());
    }
}
  • readyRead()信号会在有数据时就触发,这时可能并没有接收到含有结尾标志位(“\r\n”等)的所有数据 。我对该部分做了封装
	connect(this, &SerialPort::readyRead, this,[this]() {
        this->dataReceived();
    });

void SerialPort::dataReceived()
{
    QByteArray data = this->readAll();                      // 读取数据
    if(!data.isEmpty())                                 // 接收到数据
    {
        QString str = std::move(readBuf);  // 返回纯文本
        str += tr(data);                                // 数据是一行一行传送的,要保存所有数据
        int index = str.indexOf(endChar);                // 找到,返回索引值,找不到,返回-1
        if(index != -1)//接收到结尾标志符
        {
            readyData=std::move(str);                          // 将数据放入控件中
            dataReady();                               //数据已经准备好,发送信号
        }else{
            readBuf=std::move(str);
        }
    }
}

以下是源文件

serialport.h
#ifndef SERIALPORT_H
#define SERIALPORT_H

#include <QObject>
#include <QtSerialPort/QSerialPort>         // 提供访问串口的功能
#include <QtSerialPort/QSerialPortInfo>     // 提供系统中存在的串口信息

class SerialPort: public QSerialPort
{
    Q_OBJECT
public:
    SerialPort(QSerialPort*parent=nullptr);

    void                    refreshSerialPort();                 // 刷新串口 //关闭当前打开的串口
    bool                    setSerialPort(int index);            //设置串口
    void                    setEndMarker(QString endMarker);     //设置以 "\r\n" "\r" "\n"等结尾
    std::vector<QString>    getPortNameList();
    QString                 getData();
public slots:
    // 串口槽函数
    void                    dataReceived();                      // 接收数据
    // 串口槽函数
    void                    dataSend(QString data);              // 发送数据
signals:
    void                    dataReady();
private:

    std::vector<QString>    portNameList;                        //当前存在的串口列表
    int                     curPortIndex=0;
    QString                 readyData;                           //接收到的准备好的数据,(已去掉结尾标识符)
    QString                 readBuf;                             //未读取到结尾标识符的临时数据缓冲区
    QString                 endMarker="\r\n";
};
#endif // SERIALPORT_H
serialport.cpp
#include "serialport.h"

SerialPort::SerialPort(QSerialPort*parent)
    :QSerialPort(parent)
{
    // 参数配置
    // 波特率,波特率默认选择57600 ,禁止用户点击
    this->setBaudRate(QSerialPort::Baud9600);
    //ui->BaudBox->setDisabled(true);

    // 校验,校验默认选择无
    this->setParity(QSerialPort::NoParity);

    // 数据位,数据位默认选择8位
    this->setDataBits(QSerialPort::Data8);

    // 停止位,停止位默认选择1位
    this->setStopBits(QSerialPort::OneStop);

    // 控制流,默认选择无
    this->setFlowControl(QSerialPort::NoFlowControl);

    
    // 刷新串口
    refreshSerialPort();


    connect(this, &SerialPort::readyRead, this,[this]() {
        this->dataReceived();
    });
}


// 刷新串口
void SerialPort::refreshSerialPort()
{
    if(this->isOpen()){
        this->close();
    }
    portNameList.clear();   
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //添加新串口
    {
        portNameList.push_back(info.portName());
    }
}
bool SerialPort::setSerialPort(int index)
{
    if(this->isOpen()){
        this->close();
    }
    curPortIndex=index;
    this->setPortName(this->portNameList[index]);             //设置串口号
    if (this->open(QIODevice::ReadWrite)){
        //qDebug()<<"serial "<<this->portNameList[index]<<"open succcess"<<endl;
        return true;
    }
    //qDebug()<<"serial "<<this->portNameList[index]<<"open faild"<<endl;
    return false;
}
// 接收数据,使用read () / readLine () / readAll ()
void SerialPort::dataReceived()
{
    QByteArray data = this->readAll();                      // 读取数据
    if(!data.isEmpty())                                 // 接收到数据
    {
        QString str = std::move(readBuf);  // 返回纯文本
        str += tr(data);                                
        //qDebug() << "str info: " << str<<endl;
         // 清除之前的数据,防止追加,因为每次获取的数据不一样
        int index = str.indexOf(endMarker);                // 找到,返回索引值,找不到,返回-1
        if(index != -1)//接收到结尾标志符
        {
            readyData=std::move(str);                          // 将数据放入控件中
            dataReady();                               //数据已经准备好,发送信号
        }else{
            readBuf=std::move(str);
        }
    }
}
QString SerialPort::getData()
{
    return this->readyData;
}
// 发送数据,write ()
void SerialPort::dataSend(QString data)
{
    this->write(data.toLatin1());      // 串口发送数据
}
std::vector<QString> SerialPort::getPortNameList(){
    return this->portNameList;
}
void SerialPort::setEndMarker(QString endMarker){     //设置以 "\r\n" "\r" "\n"等结尾
    this->endMarker=endMarker;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QT是一个跨平台的开发框架,其提供了丰富的API,使得开发者能够方便地进行各种开发,包括串口通信方面。在QT中,针对串口通信的API主要为QSerialPort,其提供了丰富的接口函数,可以实现串口的打开、关闭、读取、发送等功能。 为了方便开发者使用QSerialPort,可以考虑将其封装为一个动态链接(dll)的形式,这样不仅方便开发者使用,还能够提高代码的复用性和可维护性。下面给出一个QT串口通信dll的实例: 1. 创建一个QT控制台项目 2. 在项目根目录下创建一个"serialport"文件夹 3. 在"serialport"文件夹下创建一个“serialport.h”头文件,包含如下代码: ``` #include <QObject> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> class SerialPort : public QObject { Q_OBJECT public: SerialPort(); bool open(QString portName, QSerialPort::BaudRate baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits); void close(); signals: void readyRead(QByteArray data); // 收到串口数据时发送该信号 public slots: void write(QByteArray data); // 向串口发送数据 private slots: void onReadyRead(); // 读取串口数据 private: QSerialPort *m_serialPort; }; ``` 4. 在"serialport"文件夹下创建一个“serialport.cpp”源文件,包含如下代码: ``` #include "serialport.h" SerialPort::SerialPort() { m_serialPort = new QSerialPort(this); connect(m_serialPort, SIGNAL(readyRead()), this, SLOT(onReadyRead())); } bool SerialPort::open(QString portName, QSerialPort::BaudRate baudRate, QSerialPort::DataBits dataBits, QSerialPort::Parity parity, QSerialPort::StopBits stopBits) { m_serialPort->setPortName(portName); m_serialPort->setBaudRate(baudRate); m_serialPort->setDataBits(dataBits); m_serialPort->setParity(parity); m_serialPort->setStopBits(stopBits); if (m_serialPort->open(QIODevice::ReadWrite)) { return true; } else { return false; } } void SerialPort::close() { if (m_serialPort->isOpen()) { m_serialPort->close(); } } void SerialPort::write(QByteArray data) { if (m_serialPort->isOpen()) { m_serialPort->write(data); } } void SerialPort::onReadyRead() { QByteArray data = m_serialPort->readAll(); emit readyRead(data); } ``` 5. 将"serialport.h"和"serialport.cpp"文件加入到QT项目中,并编译生成动态链接(dll) 6. 在需要使用串口通信的项目中引入"serialport.h"头文件,加载"serialport.dll"动态链接,并使用SerialPort的接口函数实现串口通信。 例如: ``` #include <QCoreApplication> #include "serialport.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); SerialPort serialPort; serialPort.open("COM1", QSerialPort::Baud9600, QSerialPort::Data8, QSerialPort::NoParity, QSerialPort::OneStop); QObject::connect(&serialPort, SIGNAL(readyRead(QByteArray)), &a, SLOT(quit())); QByteArray data("hello, serial port!"); serialPort.write(data); return a.exec(); } ``` 以上实例代码中,将创建一个SerialPort对象,指定串口名称、波特率、数据位、校验位和停止位,并调用open()函数连接串口。当收到串口数据时,SerialPort对象将发送readyRead()信号,可以使用QObject::connect()函数连接该信号到当前应用程序对象的quit()函数,从而在收到数据后退出应用程序。 总之,采用dll的形式封装QT串口通信,可以方便地实现串口通信功能,并提高代码的复用性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值