目录

前言

一、最终效果图

二、操作方法

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_OBJECTpublic: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-Fvoid 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);// 设置默认定时时长1000msconnect(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;elsehexdata = 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,选中为2if(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       += serialportgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = 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.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.uiRC_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的朋友们快速上手。​​​​​​​

完整工程​​​​​​​

基于Qt5 的串口助手开发相关推荐

  1. 基于VS2022的串口助手软件

    最近想用c++写一个基于VS2022的串口助手软件,不知道从何下手,还在找资料中...

  2. 基于QT5 + requests + MySQL + Python开发的爬虫软件

    该软件仅仅用于学习爬虫了解爬虫的相关技术和实现方法!!! 话不多说,我们直接上代码学习 仅仅用于学习 仅仅用于学习 不要总想着搞点事情,安分守己做一个爱学习的好孩子把 其实还有几个页面我是故意关掉的你 ...

  3. linux串口助手开发,linux下QT开发串口通信助手

    串口通信的应用十分广泛,所以在QT下编写一个串口通信程序就显得尤为重要.下面将一步一步叙述开发过程: 1.下载第三方QT串口类,免积分 http://download.csdn.net/detail/ ...

  4. 简单的串口助手程序开发

    1.简介 之前在烽火集团实习的时候,开发串口通信程序用的都是纯C++.感觉串口程序开发很考验人的逻辑思考能力.不过,现在好了,科研工作中,一切已存在的"利器"都可以用来为自己的&q ...

  5. QT5系列教程二---基于qcustomplot的QT5 GUI串口收发绘图软件实现

    QT5系列教程二---基于qcustomplot的QT5 GUI串口收发绘图软件实现 结构 UI部分 代码部分 step1:实现串口数据接受 串口接受数据格式 在`.pro`文件中添加`serialp ...

  6. 基于android的串口开发板,210开发板Android系统串口程序

    最近由于项目需要,花了两天时间在Android平台下编写了一个串口助手软件.硬件平台是友善之臂的tiny210开发板.起初的想法是首先基于Linux驱动做一些修改,然后自行编写HAL层代码,最后编写A ...

  7. android灯光蜂鸣器控制节点指令代码,基于stm32发送串口指令控制LED,蜂鸣器等(串口助手+原理图+显示结果)...

    本帖最后由 我累个去啊啊啊 于 2019-6-12 16:22 编辑 ///2019 6 12 更新 加入 :串口助手截图 简易问题说明 ///2019 6 11 更新  加入 :  使用的串口调试助 ...

  8. 最简单DIY基于ESP32CAM的物联网相机系统④(用调试串口助手实现串口图传)

    第一篇:最简单DIY基于ESP32CAM的物联网相机系统①(用网页实现拍照图传) 第二篇:最简单DIY基于ESP32CAM的物联网相机系统②(在JAVAWEB服务器实现图片查看器) 第三篇:最简单DI ...

  9. C#界面设计-2-PC串口助手界面的开发

    PC串口助手界面的开发 using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...

最新文章

  1. window系统mysql无法输入和无法显示中文的处理配置
  2. struts2 理解
  3. vue build text html,Vue中v-text / v-HTML使用实例代码详解_放手_前端开发者
  4. Mybatis(13)动态sql语句if/where/foreach
  5. 前端开发知识点解答-CSS-面试
  6. python 解方程 sympy_Python数据处理篇之Sympy系列(五)---解方程
  7. 华为海外版操作系统曝光?HUAWEI ARK OS现身
  8. Windows 2003系统安全+IIS下Web与FTP的完美结合(下)
  9. 全国资格考试网报平台证件照片审核处理系统报错:打开照片文件类型还是JPG或JPEG格式,请选择JPG或JPEG格式照片文件。
  10. 解决在ajax回调函数中循环遍历data数组无法获取数组下标为0之后的重复数据的问题
  11. xheditor form java_xhEditor常见问题
  12. Python修改图片分辨率(附代码) | Python工具
  13. Unity3D教程笔记——unity初始02
  14. 计算机自考毕业论文题目,自考男生发表数篇论文获专利 考取名校研究生
  15. Godaddy美国主机推荐
  16. 实验三:CART分类决策树python实现(两个测试集)(一)|机器学习
  17. 地球形状与重力场模型
  18. IO复用功能占用时,普通GPIO功能使用
  19. 计算机网络 - 面试篇
  20. js相关面试题20道

热门文章

  1. 某微信公众号运营数据分析报告
  2. win7下php 5.6连接mongodb扩展
  3. 论文阅读笔记《Regularizing Dialogue Generation by Imitating Implicit Scenarios》
  4. C# Spire.XLS 无限制 使用教程
  5. 计算机一级解释,独家秘笈计算机一级错题解释.ppt
  6. C++11标准模板(STL)- 算法(std::set_symmetric_difference)
  7. 如何配置谷歌浏览器_如何科学地使用Chrome?下载谷歌浏览器?
  8. 为Android虚拟机创建SDCard
  9. 达里奥:我阅人无数,没有一个成功人士天赋异禀 |【经纬低调分享】
  10. java gif等比例缩放_对gif动图进行缩放等处理(java)