基于Qt5 的串口助手开发

目录

前言

一、最终效果图

二、操作方法

1、创建一个新的Widgets Appliaction工程

 2、用Qt Designer 设计上位机的界面

3、代码部分

1、mainwindow.h文件内容:

2、mainwindow.cpp文件内容:

3、main.cpp文件内容:

4、pro文件:

4、代码介绍

1、添加库

2、串口配置程序

3、串口发送数据

4、串口接收数据

5、关闭串口

总结


前言

前段时间在做一个毕业设计需要一个上位机与单片机进行通讯,为了让毕业设计论文更好写一些,想着自己设计一个串口工具。花费一天时间,在网上找了大量模板,终于设计出来了,程序都是网上复制修改的,超级缝合怪,第一次使用qt开发希望我的学习心得对想要学习的同学能有所帮助。本人纯小白,还有不足地方还请大佬指点一二。

一、最终效果图

二、操作方法

1、创建一个新的Widgets Appliaction工程

 2、用Qt Designer 设计上位机的界面

 界面用到的控件还是挺多的,我直接贴出来:

   

3、代码部分

1、mainwindow.h文件内容:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>        //提供访问串口的功能
#include <QSerialPortInfo>    //提供系统中存在的串口的信息
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QPushButton>
#include <QTimer>
#include <QPainter>
#include <qinputdialog.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:

    void on_pushButton_2_clicked();
    void on_pushButton_clicked();
    void on_pushButton_3_clicked();
    void on_pushButton_4_clicked();
    void serialPort_readyRead();
    char ConvertHexChar(char ch);
    void StringToHex(QString str, QByteArray &senddata); //字符串转换为十六进制数据0-F
    void on_checkBox_clicked();
    void on_checkBox_1_clicked();
    void on_pushButton_6_clicked();
    void on_pushButton_5_clicked();
    void on_checkBox_3_stateChanged(int arg1);
    void on_pushButton_7_clicked();
    void on_pushButton_8_clicked();
    void on_pushButton_9_clicked();
    void on_pushButton_10_clicked();
    void on_pushButton_11_clicked();
    void on_pushButton_12_clicked();
    void on_pushButton_13_clicked();
    void on_pushButton_14_clicked();
    void on_pushButton_15_clicked();
    void on_pushButton_16_clicked();
    void on_pushButton_17_clicked();
    void on_pushButton_18_clicked();
    void on_pushButton_19_clicked();
    void on_pushButton_20_clicked();
    void on_pushButton_21_clicked();
    void Baud_rate_custom();

    void on_comboBox_2_activated(const QString &arg1);

private:
    Ui::MainWindow *ui;
   QSerialPort serial;

   // 定时发送-定时器
   QTimer *timSend;
};

#endif // MAINWINDOW_H

2、mainwindow.cpp文件内容:

#include "mainwindow.h"
#include "ui_mainwindow.h"

bool Hex_Input=0;
bool Hex_Output=0;
bool Out_put_1=0;
bool Baud_rate_1=0;
QString Baud_rate="9600";
long int recvNum=0;
long int sendNum=0;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->comboBox->clear();

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->comboBox->addItem(info.portName() + ": " + info.description());
    }
    this->setWindowTitle("串口助手");
    this->setMaximumSize(660,457);
    this->setMinimumSize(660,457);
    ui->pushButton->setEnabled(false);


    QPalette pl = ui->textEdit->palette();     // 获取textEdit的调色板
    pl.setColor(QPalette::Base, Qt::black);    // 设置背景色为黑色
    pl.setColor(QPalette::Text, Qt::yellow);    // 设置文本颜色为绿色
    ui->textEdit->setPalette(pl);              // 设置回调色板
    ui->textEdit->setReadOnly(true);
    ui->label_9->setText(QString::number(sendNum));
    ui->label_11->setText(QString::number(recvNum));

    timSend = new QTimer;
    timSend->setInterval(1000);// 设置默认定时时长1000ms
    connect(timSend, &QTimer::timeout, this, [=](){
        on_pushButton_clicked();
    });

    QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);

}

MainWindow::~MainWindow()
{
    delete ui;
}


//打开串口
void MainWindow::on_pushButton_2_clicked()
{


    if(ui->pushButton_2->text()==QString("打开串口"))
    {
        //设置串口名
        QString spTxt = ui->comboBox->currentText();
        spTxt = spTxt.section(':', 0, 0);//spTxt.mid(0, spTxt.indexOf(":"));
        qDebug() << spTxt;
        serial.setPortName(spTxt);
        //设置波特率
        serial.setBaudRate(ui->comboBox_2->currentText().toInt());

        // 获取串口数据位
        if(ui->comboBox_5->currentText() == "5")
        {
            serial.setDataBits(QSerialPort::Data5);
        }
        else if(ui->comboBox_5->currentText() == "6")
        {
            serial.setDataBits(QSerialPort::Data6);
        }
        else if(ui->comboBox_5->currentText() == "7")
        {
            serial.setDataBits(QSerialPort::Data7);
        }
        else if(ui->comboBox_5->currentText() == "8")
        {
            serial.setDataBits(QSerialPort::Data8);
        }

        // 获取串口奇偶校验位
        if(ui->comboBox_3->currentText() == "None")
        {
            serial.setParity(QSerialPort::NoParity);
        }
        else if(ui->comboBox_3->currentText() == "Odd")
        {
            serial.setParity(QSerialPort::OddParity);
        }
        else if(ui->comboBox_3->currentText() == "Even")
        {
            serial.setParity(QSerialPort::EvenParity);
        }

        // 获取串口停止位
        if(ui->comboBox_4->currentText() == "1")
        {
            serial.setStopBits(QSerialPort::OneStop);
        }
        else if(ui->comboBox_4->currentText() == "1.5")
        {
            serial.setStopBits(QSerialPort::OneAndHalfStop);
        }
        else if(ui->comboBox_4->currentText() == "2")
        {
            serial.setStopBits(QSerialPort::TwoStop);
        }

        //设置流控制
        serial.setFlowControl(QSerialPort::NoFlowControl);
        //打开串口
        if(!serial.open(QIODevice::ReadWrite))
        {
            QMessageBox::about(NULL,"提示","无法打开串口!");
            return;
        }

        //下拉菜单控件失能
        ui->comboBox->setEnabled(false);
        ui->comboBox_2->setEnabled(false);
        ui->comboBox_3->setEnabled(false);
        ui->comboBox_4->setEnabled(false);
        ui->comboBox_5->setEnabled(false);
        ui->pushButton_2->setText(QString("关闭串口"));
        //发送按键使能
        ui->pushButton->setEnabled(true);
        ui->pushButton_3->setEnabled(false);
    }
    else
    {
        //关闭串口
        serial.close();
        //下拉菜单控件使能
        ui->comboBox->setEnabled(true);
        ui->comboBox_2->setEnabled(true);
        ui->comboBox_3->setEnabled(true);
        ui->comboBox_4->setEnabled(true);
        ui->comboBox_5->setEnabled(true);
        ui->pushButton_2->setText(QString("打开串口"));
        //发送按键失能
        ui->pushButton->setEnabled(false);
         ui->pushButton_3->setEnabled(true);
    }
}

//串口发送字符串和16进制切换
void MainWindow::on_checkBox_1_clicked()
{
    bool status =ui->checkBox_1->isChecked();
    if(status == true)
    {
        Hex_Output=1;//16进制

    }
    else if(status == false)
    {
        Hex_Output=0;//字符串
    }
}

//发送数据
void MainWindow::on_pushButton_clicked()
{
    int a;
    QByteArray str = ui->textEdit_2->toPlainText().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

//串口接收字符串和16进制切换
void MainWindow::on_checkBox_clicked()
{
    bool status =ui->checkBox->isChecked();
    if(status == true)
    {
        Hex_Input=1;//16进制
    }
    else if(status == false)
    {
        Hex_Input=0;//字符串
    }
}

//串口接收
void MainWindow::serialPort_readyRead()
{
    if(Hex_Input==1)
    {
        QByteArray temp = serial.readAll();
        recvNum += temp.size();
        QDataStream out(&temp,QIODevice::ReadWrite);    //将字节数组读入
        while(!out.atEnd())
        {
            qint8 outChar = 0;
            out>>outChar;   //每字节填充一次,直到结束
            //十六进制的转换
            QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
            ui->textEdit->insertPlainText(str.toUpper());//大写
            ui->textEdit->insertPlainText(" ");//每发送两个字符后添加一个空格
            ui->textEdit->moveCursor(QTextCursor::End);
        }
    }
    if(Hex_Input==0)
    {
        //从接收缓冲区中读取数据
        QByteArray buffer = serial.readAll();
        recvNum += buffer.size();
        //从界面中读取以前收到的数据
        QString recv = ui->textEdit->toPlainText();
        recv += QString(buffer);
        //清空以前的显示
        ui->textEdit->clear();
        //重新显示
        ui->textEdit->append(recv);
    }
    ui->label_11->setText(QString::number(recvNum));
}

//监测串口
void MainWindow::on_pushButton_3_clicked()
{
    ui->comboBox->clear();
    //通过QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {

        //    QString serialPortInfo = info.portName() + ": " + info.description();// 串口设备信息,芯片/驱动名称
        ui->comboBox->addItem(info.portName() + ": " + info.description());
    }
}

//清空接收
void MainWindow::on_pushButton_4_clicked()
{
    ui->textEdit->clear();
    recvNum=0;
    ui->label_11->setText(QString::number(recvNum));
}

//清空发送
void MainWindow::on_pushButton_6_clicked()
{
    ui->textEdit_2->clear();
    sendNum=0;
    ui->label_9->setText(QString::number(sendNum));
}


void MainWindow::StringToHex(QString str, QByteArray &senddata) //字符串转换为十六进制数据0-F
{
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    senddata.resize(len/2);
    char lstr,hstr;

    for(int i=0; i<len; )
    {
        //char lstr,
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
}

char MainWindow::ConvertHexChar(char ch)
{
    if((ch >= '0') && (ch <= '9'))
        return ch-0x30;
    else if((ch >= 'A') && (ch <= 'F'))
        return ch-'A'+10;
    else if((ch >= 'a') && (ch <= 'f'))
        return ch-'a'+10;
    else return ch-ch;//不在0-f范围内的会发送成0
}

//保存接收文件
void MainWindow::on_pushButton_5_clicked()
{
    if(ui->textEdit->toPlainText()==NULL)
    {
        QMessageBox::information(this,tr("注意"),tr("当前文本没有内容"),QMessageBox::Ok);
    }
    else {
        QString fileName = QFileDialog::getSaveFileName(
                    this, tr("save txt file"),
                    "/", tr("Txt files(*.txt)"));
        QFile f1(fileName);
        f1.open(QIODevice::WriteOnly|QIODevice::Text);
        QTextStream str(&f1);
        str<<ui->textEdit->toPlainText();
        f1.close();
    }
}

//定时发送 选择复选框
void MainWindow::on_checkBox_3_stateChanged(int arg1)
{
    // 获取复选框状态,未选为0,选中为2
    if(arg1 == 0){
        timSend->stop();
        // 时间输入框恢复可选
        ui->txtSendMs->setEnabled(true);
    }else{
        // 对输入的值做限幅,小于1ms会弹出对话框提示
        if(ui->txtSendMs->text().toInt() >= 1){
            timSend->start(ui->txtSendMs->text().toInt());// 设置定时时长,重新计数
            // 让时间输入框不可选,避免误操作(输入功能不可用,控件背景为灰色)
            ui->txtSendMs->setEnabled(false);
        }else{
            ui->checkBox_3->setCheckState(Qt::Unchecked);
            QMessageBox::critical(this, "错误提示", "定时发送的最小间隔为 1ms\r\n请确保输入的值 >=1");
        }
    }
}



void MainWindow::on_pushButton_7_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_1->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_8_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_2->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_9_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_3->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_10_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_4->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_11_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_5->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_12_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_6->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_13_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_7->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_14_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_8->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_15_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_9->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_16_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_10->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_17_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_11->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_18_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_12->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_19_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_13->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_20_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_14->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

void MainWindow::on_pushButton_21_clicked()
{
    int a;
    QByteArray str = ui->txtSendMs_15->text().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送到串口
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}



void MainWindow::Baud_rate_custom()
{
    bool ok;
    int  text = QInputDialog::getInt(this, tr("自定义波特率"),tr("请输入波特率"),9600,1,9999999,0, &ok);
    if (ok && text >= 1)
    {
        Baud_rate = QString::number(text);
    }
}


void MainWindow::on_comboBox_2_activated(const QString &arg1)
{
    if(arg1=="custom")
    {
        Baud_rate_custom();
        ui->comboBox_2->addItem(Baud_rate);
    }
}


作者也是小白,代码还有很多问题,希望大家指正,代码太长,完整工程我会上传资源。

3、main.cpp文件内容:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

4、pro文件:

#-------------------------------------------------
#
# Project created by QtCreator 2022-03-04T17:01:41
#
#-------------------------------------------------

QT       += core gui
QT       += serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = demo_3
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

RC_ICONS = demo_22.ico

4、代码介绍

博主也不是废话很多的人,也不喜欢直接看一些原理,喜欢直接上手去做一个项目,通过做项目的过程中去学习和了解,所以直接上源码,希望大家在程序能有效果的同时去慢慢了解,废话不多说现在介绍下代码。

1、添加库

QT5是自带QSerialPor这个类,使用时需要在pro文件里面添加:

QT       += serialport

其次需要在mainwindow.cpp文件夹中加入以下两个头文件:

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

2、串口配置程序

//创建串口对象
QSerialPort serial;
//设置串口名为COM5
serial.setPortName("COM5");
//设置波特率为115200
serial.setBaudRate(QSerialPort::Baud115200);
//设置数据位数为8位
serial.setDataBits(QSerialPort::Data8);
//设置奇偶校验无
serial.setParity(QSerialPort::NoParity); 
//设置停止位为一位
serial.setStopBits(QSerialPort::OneStop);
//设置流控制为无
serial.setFlowControl(QSerialPort::NoFlowControl);
//打开串口
serial.open(QIODevice::ReadWrite);

以上程序在mainwindow.cpp文件中,主要配置串口工作模式。

3、串口发送数据

//发送数据
void MainWindow::on_pushButton_clicked()
{
    int a;
    QByteArray str = ui->textEdit_2->toPlainText().toUtf8();//从LineEdit得到字符串
    if(Hex_Output==0)
    {
        a= serial.write(str);//发送完毕后返回发送的字节数
    }
    else if(Hex_Output==1)
    {
        int len = str.length();
        if(len%2 == 1)   //如果发送的数据个数为奇数的,则在前面最后落单的字符前添加一个字符0
        {
            str = str.insert(len-1,'0'); //insert(int position, const QString & str)
        }
        QByteArray senddata;
        StringToHex(str,senddata);//将str字符串转换为16进制的形式
        a= serial.write(senddata);//发送完毕后返回发送的字节数
    }

    if(a > 0)
    {
        // 发送字节计数
        sendNum += a;
        // 状态栏显示计数值
        ui->label_9->setText(QString::number(sendNum));
    }
}

上段函数是发送数据,最终使用write函数便可以把字节数组中的字节发送出去。上段程序Hex_Output是判断以16进制发送还是以字符串发送。a是用来统计发送的数据字节数,最后统计到sendNum

4、串口接收数据

//连接信号和槽
QObject::connect(&serial, &QSerialPort::readyRead, this, &MainWindow::serialPort_readyRead);

//串口接收
void MainWindow::serialPort_readyRead()
{
    if(Hex_Input==1)
    {
        //从接收缓冲区中读取数据
        QByteArray temp = serial.readAll();
        recvNum += temp.size();//记录接收数据字节数
        QDataStream out(&temp,QIODevice::ReadWrite);    //将字节数组读入
        while(!out.atEnd())
        {
            qint8 outChar = 0;
            out>>outChar;   //每字节填充一次,直到结束
            //十六进制的转换
            QString str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
            ui->textEdit->insertPlainText(str.toUpper());//大写
            ui->textEdit->insertPlainText(" ");//每发送两个字符后添加一个空格
            ui->textEdit->moveCursor(QTextCursor::End);
        }
    }
    if(Hex_Input==0)
    {
        //从接收缓冲区中读取数据
        QByteArray buffer = serial.readAll();
        recvNum += buffer.size();
        //从界面中读取以前收到的数据
        QString recv = ui->textEdit->toPlainText();
        recv += QString(buffer);
        //清空以前的显示
        ui->textEdit->clear();
        //重新显示
        ui->textEdit->append(recv);
    }
    ui->label_11->setText(QString::number(recvNum));
}

串口在收到数据后,会将数据存入接收缓冲区。通过readAll()函数读取缓存区数据,在这里为了实时读取数据,编写一个槽函数来读取数据。

5、关闭串口

serial->close();

串口不使用的时候可以使用serial->close();关闭串口。

总结

博主也是刚学习qt编程,串口功能实现很多是借鉴​​​​​​​github上开源项目,有很多代码都是拼凑的,有不对的希望大家指正,再次也很希望这个教程能让刚学习qt的朋友们快速上手。​​​​​​​

完整工程​​​​​​​

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值