Qt之串口案例

概述:

1. 今天跟大家分享下Qt的串口使用,本案例是之前配合公司项目调试自己编写的小软件
2. Qt使用窗口的一些函数这里就不该大家一一介绍,函数作用直接会在代码的注释说明
3. 大家忽略我的注释格式,当时项目测试着急,所以简单注释了下
4. 如果大家想知道串口的通信方式以及连线方式可以参考我前面的文章
5. 本案例数据模式是ACELL格式,本案例带有收发数据记录存储功能
6. 本案例串口的一写基本配置写死了,大家可以根据界面判断进行设置相关数据

代码示例:

.pro

#-------------------------------------------------
#
# Project created by QtCreator 2019-08-01T12:20:47
#
#-------------------------------------------------
#	这里要把串口库添加上 serialport
QT       += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Seri
TEMPLATE = app


SOURCES += main.cpp\
        Seri.cpp

HEADERS  += Seri.h

FORMS    += Seri.ui

DISTFILES +=

RESOURCES += \
    image.qrc

.h

#ifndef SERI_H
#define SERI_H

#include <QWidget>
#include <QWidget>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QtSerialPort/qserialport.h>
#include <QtSerialPort/qserialportinfo.h>

namespace Ui {
class Seri;
}

class Seri : public QWidget
{
    Q_OBJECT

public:
    explicit Seri(QWidget *parent = 0);
    ~Seri();
private:
    inline void myDebugCall();                                      //自调用解析函数
    inline void mySend(const char* sendData,const QString text);    //自调用发送函数
    inline void myState();                                          //自调用对状态灯刷新

signals:
    SIGNAL_recv(QByteArray arry);	//接收数据通过信号将数据发送出去
private slots:
    void on_Open_clicked();         //打开串口
    void recv_Com();                //串口来消息响应槽
    void recvAnaly();               //接收立即处理信号槽--信号可以当槽使用--同样也可以emit--哈哈--奇葩吧
    void on_Write_clicked();        //发送数据
    void on_btnA_save_clicked();    //保存接收数据按钮
    void on_btnB_save_clicked();    //保存发送数据按钮
    void on_btn_close_clicked();    //关闭串口按钮
    void on_pushButton_clicked();   //清空显示区
private:
    QSerialPort* m_serial;          //串口
    QByteArray str;                 //私有存储接收数据成员变量
    bool click;                     //判断打开串口按钮是否被点击
private:
    Ui::Seri *ui;
};

#endif // SERI_H

.cpp

#include "Seri.h"
#include "ui_Seri.h"


Seri::Seri(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Seri)
{
    ui->setupUi(this);

    m_serial = new QSerialPort(this);                                           //创建串口 QSerialPort() 括号中可以设置参数 串口名... 待研究完善

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())     //遍历获取当前可使用串口设置到comboBoxSeri控件上
    {
        if(ui->comboBoxSeri->currentText() != info.description())
        {
            ui->comboBoxSeri->addItem(info.portName());							//将本机可以使用串口名加载到界面
        }
    }
    connect(m_serial,SIGNAL(readyRead()),SLOT(recv_Com()));                     //接到串口数据响应

    ui->label_State->setProperty("state","No");                                 //状态灯初始为红色 没有打开
    
    this->click = false;

}

Seri::~Seri()
{
    delete ui;
}
/*
 * 自调用数据解析打印
 */
void Seri::myDebugCall()
{
    for (int i = 0;i < str.size();i++)
    {
        qDebug() << str.at(i);
    }
}

/*
 * 统一数据发送函数
 */
void Seri::mySend(const char *sendData, const QString text)
{
    m_serial->write(sendData);
    QString str = sendData + text;
    ui->sendtextEdit->append(str);
    ui->sendtextEdit->append("|---------------------------------------------------------|");
}
/*
 *刷新状态灯
 */
void Seri::myState()
{
    style()->unpolish(ui->label_State);
    style()->polish(ui->label_State);
    update();
}

/*
 * 打开串口按钮
 */
void Seri::on_Open_clicked()
{
    m_serial->setPortName(ui->comboBoxSeri->currentText());
    if(m_serial->open(QIODevice::ReadWrite) == true) { ui->label_State->setProperty("state","Ok");  click = true;/*判断打开串口是否打开成功*/ }
    else{ui->label_State->setProperty("state","No");}
    m_serial->setBaudRate(QSerialPort::Baud9600,QSerialPort::AllDirections);    //设置波特率和读写方向
    m_serial->setDataBits(QSerialPort::Data8);                                  //设置数据位8
    m_serial->setParity(QSerialPort::OddParity);                                //校验位
    m_serial->setStopBits(QSerialPort::OneStop);                                //一位停止位
    m_serial->setFlowControl(QSerialPort::NoFlowControl);                       //无流控制--好像并没有什么用

    myState();                                                                  //刷新状态灯 此控制后期要加到串口是否打开成功逻辑中
}

/*
 * 接受数据槽 并在界面上显示内容
 */
void Seri::recv_Com()
{
    QByteArray temp = m_serial->readAll();            //在缓冲区读取数据--此处应该循环获取数据 直到\n为止
    if(!temp.isEmpty())                               //如果读到数据不为空
    {
        ui->recvBrowser->append(QString(temp));       //把接到的数据现在界面显示后在进行逻辑处理
    }
    this->str = temp;                                 //把收到的数据利用成员函数进行存储方便后面解析
    temp.clear();                                     //接到数据进行存储后进行清空操作
    emit recvAnaly();                                 //发出信号 有新数据到来 响应recvAnaly()进行解析
}
/*
 * 发送数据按钮
 */
void Seri::on_Write_clicked()
{
    m_serial->write(ui->sendtextEdit->toPlainText().toLatin1());
    ui->sendtextEdit->clear();                                                  //发送后直接清空显示区

    QByteArray temp = m_serial->readAll();
    ui->sendtextEdit->setText(temp);

}

/*
 * 通过recv_Com(槽)接收到数据发出信号进行逻辑分发处理
 */
void Seri::recvAnaly()
{
    myDebugCall();
    //此处进行数据解析
}

/*
 * 保存记录的收发数据按钮
 */
void Seri::on_btnA_save_clicked()
{
    QString textFile = QFileDialog::getSaveFileName(this,tr("Save txt"),"",tr("text (*.txt)"));
    QFile file(textFile);
    if(!file.open(QFile::WriteOnly | QFile::Text)) return;
    QTextStream out(&file);     //分行写入文件
    out << ui->recvBrowser->toPlainText();
}

/*
 * 关闭串口按钮
 */
void Seri::on_btn_close_clicked()
{
    m_serial->close();
    m_time->stop();
    ui->label_State->setProperty("state","No");
    myState();
}

/*
 * 保存数据发送按钮
 */
void Seri::on_btnB_save_clicked()
{
    QString textFile = QFileDialog::getSaveFileName(this,tr("Save txt"),"",tr("text (*.txt)"));
    QFile file(textFile);
    if(!file.open(QFile::WriteOnly | QFile::Text)) return;
    QTextStream out(&file);   //分行写入文件
    out << ui->sendtextEdit->toPlainText();
}

/*
 * 清空显示区按钮
 */
void Seri::on_pushButton_clicked()
{
    ui->recvBrowser->clear();
    ui->sendtextEdit->clear();
}

运行效果图:

在这里插入图片描述

over:

欢迎大家关注作者在文末评论、点赞、转发以及批评指正!
如果大家有更好的方法或有问题可以在文末评论一起讨论!
共同学习!
共同进步!

文末一句话:

一晃来北京4个年头了,从机械到销售再到一个程序猿,在这一路感谢家人的鼓励和支持,也感谢这些年自己的坚持和一颗敢幻想的心,最后再补充一句:你自己要是想要干什么确定好,接下来就沿着这个目标坚持不懈的努力下去,干就完了!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值