Qt 编写串口助手

效果图

注:16进制显示没有用空格分开

1、在项目管理文件(.pro) 里面添加 

QT       += serialport  //加入串口模块

2、引用头文件

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

3、界面设计

4、定义一个 QSerialPort 类

QSerialPort Serial;

5、串口设置需要的函数

Serial.setPortName("COM6");                      //设置端口号
Serial.setBaudRate(9600);                        //设置波特率
Serial.setDataBits(QSerialPort::Data8);          //设置数据位
Serial.setStopBits(QSerialPort::OneStop);        //设置停止位
Serial.setParity(QSerialPort:NoParity);          //设置奇偶校验
Serial.setFlowControl(QSerialPort::NoFlowControl);//设置流控制模式

6、串口开关控制

void subwidget::on_open_Button_clicked()
{
    if(ui->open_Button->text() == QString("打开串口"))  //串口未打开
    {
        //设置端口号
        Serial.setPortName(ui->comBox->currentText());
        //设置波特率
        Serial.setBaudRate(ui->bandRateBox->currentText().toInt());
        //设置数据位
        switch (ui->dataBitBox->currentText().toInt())
        {
            case 8: Serial.setDataBits(QSerialPort::Data8); break;
            case 7: Serial.setDataBits(QSerialPort::Data7); break;
            case 6: Serial.setDataBits(QSerialPort::Data6); break;
            case 5: Serial.setDataBits(QSerialPort::Data5); break;
            default: break;
        }
        //设置停止位
        switch (ui->stopBitBox->currentText().toInt())
        {
            case 1: Serial.setStopBits(QSerialPort::OneStop);break;
            case 2: Serial.setStopBits(QSerialPort::TwoStop);break;
            default:break;
        }
        //设置校验方式
        switch (ui->checkoutBox->currentIndex())
        {
            case 0: Serial.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置流控制模式
        Serial.setFlowControl(QSerialPort::NoFlowControl);
        //打开串口
        if(Serial.open(QIODevice::ReadWrite)==false)
        {
            QMessageBox::warning(NULL , "提示", "串口打开失败!");
            return;
        }
        // 失能串口设置控件
        ui->comBox->setEnabled(false);
        ui->checkoutBox->setEnabled(false);
        ui->bandRateBox->setEnabled(false);
        ui->dataBitBox->setEnabled(false);
        ui->stopBitBox->setEnabled(false);
        ui->search_Button->setEnabled(false);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("关闭串口"));
    }
    else       //串口已经打开
    {
        Serial.close();
        // 使能串口设置控件
        ui->comBox->setEnabled(true);
        ui->checkoutBox->setEnabled(true);
        ui->bandRateBox->setEnabled(true);
        ui->dataBitBox->setEnabled(true);
        ui->stopBitBox->setEnabled(true);
        ui->search_Button->setEnabled(true);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("打开串口"));
    }
}

7、检测可用端口

void subwidget::on_search_Button_clicked()
{
    // 清除当前显示的端口号
    ui->comBox->clear();
    //检索端口号
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comBox->addItem(info.portName());
    }
}

8、串口发送

void subwidget::on_send_Button_clicked()
{
    if(Serial.isOpen()==false)  //判断串口是否正常打开
    {
        QMessageBox::warning(NULL , "提示", "请打开串口!");
        return;
    }
    //toPlainText() 转换为纯文本格式
    //toUtf8() 转换为UTF-8 编码
    QByteArray senddata = ui->SendEdit->toPlainText().toUtf8();

    //判断是否有非16进制字符
    if(ui->send16Box->isChecked()==true) //勾选了16进制发送
     {

        int cnt = senddata.size();          //要发送数据的长度

        char *data = senddata.data();
        for(int i=0;i<cnt;i++)//判断是否有非16进制字符
        {
            if(data[i]>='0' && (data[i]<='9'))
                continue;
            else if(data[i]>='a' && (data[i]<='f'))
                continue;
            else if(data[i]>='A' && (data[i]<='F'))
                continue;
            else if(data[i] == ' ')     //输入为空格
                continue;
            else
            {
                QMessageBox::warning(NULL , "提示", "输入非16进制字符!");
                return;
            }
        }

        //字符串转化为16进制数   "1234" --> 0X1234
        //转换时会自动除去非16进制字符
        senddata = senddata.fromHex(senddata);
    }
    //勾选了发送新行
    if(ui->newlineBox->isChecked()==true)
    {
        int cnt = senddata.size();
        senddata = senddata.insert(cnt,"\r\n"); //插入回车换行符
    }

    Serial.write(senddata); //通过串口发送数据
}

9、在接收窗口显示收到的数据

        注:测试时不是一次性全部接收串口发送的数据,没有实现16进制字符用空格分开。

void subwidget::Serial_read()
{
    //读取串口收到的数据
    QByteArray buffer = Serial.readAll();
    //判断是否需要16进制显示
    if(ui->show16Box->isChecked()==true)
    {
        buffer = buffer.toHex() ;//转换为16进制 例:"1234" -->“31323334”
    }
    QString receive = QString(buffer);
    //在接受窗口显示收到的数据
    ui->receiveEdit->insertPlainText(receive);
}


注:需要使用connect()关联
    connect(&Serial, &QSerialPort::readyRead , this , &subwidget::Serial_read);

完整程序

.H 文件

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>

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

namespace Ui {
class subwidget;
}

class subwidget : public QWidget
{
    Q_OBJECT

public:
    explicit subwidget(QWidget *parent = nullptr);
    ~subwidget();

private:
    Ui::subwidget *ui;

public:

    QSerialPort Serial;

private slots:
    void on_open_Button_clicked();
    void on_send_Button_clicked();
    void on_search_Button_clicked();
    void Serial_read();
    void on_clear_r_Button_clicked();
};

#endif // SUBWIDGET_H

cpp文件

#include "subwidget.h"
#include "ui_subwidget.h"
#include <QMessageBox>
#include <QDataStream>
subwidget::subwidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::subwidget)
{
    ui->setupUi(this);

    this->setWindowTitle("TEST子窗口");                //设置子窗口标题

    connect(&Serial, &QSerialPort::readyRead , this , &subwidget::Serial_read);

    ui->bandRateBox->setCurrentIndex(0);    //波特率默认9600

}

subwidget::~subwidget()
{
    delete ui;
}
//串口控制 槽函数
void subwidget::on_open_Button_clicked()
{
    if(ui->open_Button->text() == QString("打开串口"))  //串口未打开
    {
        //设置端口号
        Serial.setPortName(ui->comBox->currentText());
        //设置波特率
        Serial.setBaudRate(ui->bandRateBox->currentText().toInt());
        //设置数据位
        switch (ui->dataBitBox->currentText().toInt())
        {
            case 8: Serial.setDataBits(QSerialPort::Data8); break;
            case 7: Serial.setDataBits(QSerialPort::Data7); break;
            case 6: Serial.setDataBits(QSerialPort::Data6); break;
            case 5: Serial.setDataBits(QSerialPort::Data5); break;
            default: break;
        }
        //设置停止位
        switch (ui->stopBitBox->currentText().toInt())
        {
            case 1: Serial.setStopBits(QSerialPort::OneStop);break;
            case 2: Serial.setStopBits(QSerialPort::TwoStop);break;
            default:break;
        }
        //设置校验方式
        switch (ui->checkoutBox->currentIndex())
        {
            case 0: Serial.setParity(QSerialPort::NoParity);break;
            default:break;
        }
        //设置流控制模式
        Serial.setFlowControl(QSerialPort::NoFlowControl);
        //打开串口
        if(Serial.open(QIODevice::ReadWrite)==false)
        {
            QMessageBox::warning(NULL , "提示", "串口打开失败!");
            return;
        }
        // 失能串口设置控件
        ui->comBox->setEnabled(false);
        ui->checkoutBox->setEnabled(false);
        ui->bandRateBox->setEnabled(false);
        ui->dataBitBox->setEnabled(false);
        ui->stopBitBox->setEnabled(false);
        ui->search_Button->setEnabled(false);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("关闭串口"));
    }
    else       //串口已经打开
    {
        Serial.close();
        // 使能串口设置控件
        ui->comBox->setEnabled(true);
        ui->checkoutBox->setEnabled(true);
        ui->bandRateBox->setEnabled(true);
        ui->dataBitBox->setEnabled(true);
        ui->stopBitBox->setEnabled(true);
        ui->search_Button->setEnabled(true);
        //调整串口控制按钮的文字提示
        ui->open_Button->setText(QString("打开串口"));
    }
}

void subwidget::on_search_Button_clicked()
{
    // 清除当前显示的端口号
    ui->comBox->clear();
    //检索端口号
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comBox->addItem(info.portName());
    }
}

void subwidget::on_clear_r_Button_clicked()
{
    ui->receiveEdit->clear();
}

void subwidget::on_send_Button_clicked()
{
    if(Serial.isOpen()==false)  //判断串口是否正常打开
    {
        QMessageBox::warning(NULL , "提示", "请打开串口!");
        return;
    }
    //toPlainText() 转换为纯文本格式
    //toUtf8() 转换为UTF-8 编码
    QByteArray senddata = ui->SendEdit->toPlainText().toUtf8();

    //判断是否有非16进制字符
    if(ui->send16Box->isChecked()==true) //勾选了16进制发送
     {

        int cnt = senddata.size();          //要发送数据的长度

        char *data = senddata.data();
        for(int i=0;i<cnt;i++)//判断是否有非16进制字符
        {
            if(data[i]>='0' && (data[i]<='9'))
                continue;
            else if(data[i]>='a' && (data[i]<='f'))
                continue;
            else if(data[i]>='A' && (data[i]<='F'))
                continue;
            else if(data[i] == ' ')     //输入为空格
                continue;
            else
            {
                QMessageBox::warning(NULL , "提示", "输入非16进制字符!");
                return;
            }
        }

        //字符串转化为16进制数   "1234" --> 0X1234
        //转换时会自动除去非16进制字符
        senddata = senddata.fromHex(senddata);
    }
    //勾选了发送新行
    if(ui->newlineBox->isChecked()==true)
    {
        int cnt = senddata.size();
        senddata = senddata.insert(cnt,"\r\n"); //插入回车换行符
    }

    Serial.write(senddata); //通过串口发送数据
}
//显示收到的数据
void subwidget::Serial_read()
{
    //读取串口收到的数据
    QByteArray buffer = Serial.readAll();
    //判断是否需要16进制显示
    if(ui->show16Box->isChecked()==true)
    {
        buffer = buffer.toHex() ;//转换为16进制 例:"1234" -->“31323334”
    }
    QString receive = QString(buffer);
    //在接受窗口显示收到的数据
    ui->receiveEdit->insertPlainText(receive);
}
发布了24 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CSDNZSX/article/details/89335600