基于VS2022+Qt5+C++的串口助手开发

目录

一、前言 

二、环境准备

三、创建QT串口项目 

​编辑 四、串口项目实现

1.ui界面设计

2.添加QT串口模块

3.功能实现 

①串口扫描

 ②波特率、停止位等设置

③接收数据

④发送数据

五、最终效果

六、总结


一、前言 

如果有人之前看过我文章的话应该知道,我之前用python+pyqt5写过一版串口助手。没看过的也不要紧,我贴在下面,大家可以浅浅看一下。最近由于工作需要,开始接触C++以及QT,就想着能不能用C++和QT重写一下串口助手。于是就有了这篇文章单纯记录一下,接下来听我娓娓道来~

基于Python+Pycharm+PyQt5的串口助手开发_基于python+pyqt5的串口助手-CSDN博客文章浏览阅读2.3k次,点赞43次,收藏30次。本期带来的基于PyQt5的串口助手开发,实现串口通信。_基于python+pyqt5的串口助手https://blog.csdn.net/weixin_44765053/article/details/135347552?spm=1001.2014.3001.5502

二、环境准备

操作系统:win 10

编辑器:VS2022、QT5.14

语言及版本:C++

最终实现的功能:串口选择、串口状态显示、发送数据、接收数据、数据显示(ASCII)

首先假设你已经安装好了VS以及QT(如果不清楚的比较多的话麻烦评论区留言,后续我出一篇文章详细介绍),那么如何在VS里面新建QT项目并编写代码呢?我们需要安装Qt VS Tools插件

①打开Visual Studio点击右上角的扩展,然后点击管理扩展。

 ②搜索并安装"Qt Visual Studio Tools"插件,然后重启Visual Studio。

③重启后依次点击,扩展-->Qt VS Tools-->Qt Versions ④点击path,选择你QT安装时候编译路径,即qmake.exe所在的目录。例如我这边显示D:\QT\5.14.0\msvc2017_64,但其实qmake.exe是在bin文件下面

三、创建QT串口项目 

①打开VS中,选择创建新项目。在搜索框输入Qt Widget Application,选择Qt Widget Application点击下一步。

② 修改项目名称以及项目位置,然后点击创建。

③一直点击默认的next直至以下界面,我们选择QWidget。

 四、串口项目实现

1.ui界面设计

在右侧点击Form Files,然后双击ui文件进行界面设计。这里我们就偷个小懒,直接沿用pyqt项目的ui界面。

PS:如果这里出现无法打开ui文件的,可以《扩展》-> 《Qt vs tools》-> 《options》-> 《Qt》-> 《general》 -> 《Qt Designer》 -> 《run in detached window》 -> true

2.添加QT串口模块

在Qt中,串口通信的核心是QSerialPortQSerialPortInfo这两个类。

  • QSerialPort:这个类提供了与串口进行通信的功能。它可以用于打开、关闭串口,设置串口的参数如波特率、数据位、停止位等,还可以通过这个类发送和接收数据。QSerialPort是串口助手中最关键的类,它让我们能够轻松地与硬件进行数据通信。

  • QSerialPortInfo:这个类用于提供系统中可用的串口信息。通过它,我们可以获取到当前系统中所有可用串口的名称、描述信息等。它主要用于列出可用串口供用户选择。

但是当我们直接#include <QSerialPort>、#include <QSerialPortInfo>时候会报错,需要将其添加到Qt Modules。依次点击,项目-->serial和属性-->Qt Project Settings-->Qt Modules-->添加serial port


 

3.功能实现 

主要功能包括:

  • 串口扫描:定时每秒扫描现存串口列表,并将其添加到ComboBox。
  • 波特率设置:提供一个下拉列表,用户可以选择常用的波特率。
  • 数据接收:接收数据,并以十六进制显示。
  • 数据发送:包括十六进制发送、定时发送数据等待。

①串口扫描

#include "serial2.h"SerialPortScanner::SerialPortScanner(QComboBox* comboBox) // 构造函数,传入一个QComboBox指针作为参数: m_comboBox(comboBox), m_timer(new QTimer(this)) // 初始化成员变量m_comboBox, m_timer
{// 创建一个定时器,每1000毫秒(1秒)触发一次connect(m_timer, &QTimer::timeout, this, &SerialPortScanner::scanSerialPorts); // 连接定时器的超时信号和scanSerialPorts槽函数m_timer->start(1000); // 启动定时器
}void SerialPortScanner::scanSerialPorts()
{QList<QString> m_newports;  // 新的串口列表// 获取可用的串口列表QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();// 遍历串口列表,将每个串口的名称添加到QComboBox中for (const QSerialPortInfo& portInfo : portList) {m_newports.append(portInfo.portName());  // 将串口名称添加到列表中}if (m_newports != m_portNames) {m_portNames = m_newports; // 更新旧的串口列表m_comboBox->clear(); // 清空QComboBoxm_comboBox->addItems(m_portNames); // 将新的串口列表添加到QComboBox中}
}

效果如下:

 

 ②波特率、停止位等设置

#include "serial2.h"SerialPortSet::SerialPortSet(Ui::serial2Class* ui, QObject* parent)  // 构造函数: QObject(parent),serialPort(new QSerialPort(this)),m_ui(ui)
{}// 获取波特率
QSerialPort::BaudRate SerialPortSet::getBaudRate(const QString& baudRateStr) {  static const QMap<QString, QSerialPort::BaudRate> baudRateMap = {  {"1200", QSerialPort::Baud1200},  // 1200{"2400", QSerialPort::Baud2400},  // 2400{"4800", QSerialPort::Baud4800},  // 4800{"9600", QSerialPort::Baud9600},  // 9600{"19200", QSerialPort::Baud19200},  // 19200{"38400", QSerialPort::Baud38400}, // 38400};return baudRateMap.value(baudRateStr, QSerialPort::Baud9600); // 返回对应的波特率
}
// 获取数据位
QSerialPort::DataBits SerialPortSet::getDataBits(const QString& dataBitsStr) {static const QMap<QString, QSerialPort::DataBits> dataBitsMap = {{"5", QSerialPort::Data5},  // 5{"6", QSerialPort::Data6},  // 6{"7", QSerialPort::Data7}, // 7{"8", QSerialPort::Data8}  // 8};return dataBitsMap.value(dataBitsStr, QSerialPort::Data8);  // 返回对应的数据位
}// 获取停止位
QSerialPort::StopBits SerialPortSet::getStopBits(const QString& stopBitsStr) {static const QMap<QString, QSerialPort::StopBits> stopBitsMap = {{"1", QSerialPort::OneStop},  // 1{"1.5", QSerialPort::OneAndHalfStop},  // 1.5{"2", QSerialPort::TwoStop}  // 2};return stopBitsMap.value(stopBitsStr, QSerialPort::OneStop);  // 返回对应的停止位
}// 获取奇偶校验位
QSerialPort::Parity SerialPortSet::getParityBits(const QString& parityStr) {static const QMap<QString, QSerialPort::Parity> parityMap = {{"NONE", QSerialPort::NoParity},  // 无{"ODD", QSerialPort::OddParity},  // 奇{"EVEN", QSerialPort::EvenParity}  // 偶};return parityMap.value(parityStr, QSerialPort::NoParity); // 返回对应的奇偶校验位
}void SerialPortSet::open_Port()
{// 获取各项设置QSerialPort::BaudRate baudRate = getBaudRate(m_ui->comboBox_Baud->currentText());  // 获取波特率QSerialPort::DataBits dataBits = getDataBits(m_ui->comboBox_Data->currentText());  // 获取数据位QSerialPort::StopBits stopBits = getStopBits(m_ui->comboBox_Stop->currentText());  // 获取停止位QSerialPort::Parity parity = getParityBits(m_ui->comboBox_Check->currentText());  // 获取校验位// 设置串口参数serialPort->setPortName(m_ui->comboBox_COM->currentText());  // 设置串口名称serialPort->setBaudRate(baudRate);  // 设置波特率serialPort->setDataBits(dataBits);  // 设置数据位serialPort->setStopBits(stopBits);  // 设置停止位serialPort->setParity(parity);  // 设置校验位if (serialPort->open(QIODevice::ReadWrite)) {  // 尝试打开串口m_ui->pushButton_Open->setText("关闭串口");  // 更新按钮文本}else {// 如果无法打开串口,弹出错误信息QMessageBox::warning(m_ui->label, "错误", "无法打开串口: " + serialPort->errorString());  // 弹出警告框}}
}

效果如下: 

 

③接收数据

void SerialPortCommunication::readData()  // 当有数据可读时,读取数据
{if (m_serialPort->isOpen()){  // 如果串口打开,则读取数据QByteArray data = m_serialPort->readAll();  // 读取数据m_ui->textEdit_receive->insertPlainText(QString::fromUtf8(data));  // 将数据插入到文本框中}m_ui->textEdit_receive->moveCursor(QTextCursor::End);
}

④发送数据

void SerialPortCommunication::sendData()  // 发送数据函数
{QString inputData = m_ui->textEdit_Send->toPlainText();  // 获取发送数据if (m_serialPort->isOpen() && !inputData.isEmpty()) {  // 如果串口打开且发送数据不为空,则发送数据QByteArray byteArray;  // 创建字节数组byteArray = inputData.toUtf8();m_serialPort->write(byteArray);  // 发送数据
}

由于篇幅有限,以上只贴了主要功能实现代码。

五、最终效果

 老样子,我们来看看最终与其他串口通信效果。

QT串口助手

 

六、总结

通过本文的详细讲解,我们完成了一个基于VS2022和Qt5的串口助手的开发。该串口助手实现了串口扫描、开关串口、数据接收和数据发送等核心功能,能够帮助用户方便地与串口设备进行通信和调试。

在开发过程中,我们深入了解了QSerialPortQSerialPortInfo类的应用,通过它们轻松实现了串口的操作和管理。同时,本文还详细介绍了如何在Qt中设计用户界面,使我们的工具不仅功能完善,而且使用起来简洁直观。

希望通过这篇文章,你能够更好地掌握Qt开发与串口通信相关的知识,并将这些技能应用到实际项目中。如果你在开发过程中遇到任何问题,欢迎在评论区交流讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/402384.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hbase架构和读写流程

目录 1.概述 2.简介 3.Hbase架构 4.数据模型 5.Hbase写流程 6.Hbase读数据 1.概述 本篇文章将简单的讲述Hbase的架构和读写流程&#xff0c;多为理论部分&#xff0c;不涉及API代码 2.简介 从官方介绍可以知道,Hbase是一种分布式、可扩展、支持海量数据存储的 NoSQ…

Element-UI动态生成的表单元素验证示例

模拟数据 tableData: [{name: "系统1",score: 0,children:[{name: "一号子系统",score: 0,}]},{name: "系统2",score: 0,children:[{name: "3号子系统",score: 0,}]},{name: "系统3",score: 0,children:[{name: "5号子…

python-docx在word文件表格中指定行下插入新一行并填充值

from docx import Document from copy import deepcopydef insert_row_after_specific_value(doc, table_index, column_header, target_value, new_row_data):# 加载文档# doc doc_path# 检查表格索引是否有效if table_index > len(doc.tables):print("文档中没有足够…

matlab 音频音量处理(音量大小按照dB调节)

1 音量(声压级)以分贝(dB)表示的计算公式为: 2 % 已知的 x 值 x = 0:-1:-127; % 在这里填入 x 的具体值% 计算 y %y = 10

江理工文档管理系统的设计与实现

TOC springboot148江理工文档管理系统的设计与实现 绪论** 1.1 研究背景 在这个推荐个性化的时代&#xff0c;采用新技术开发一个文档系统来分享和展示内容是一个永恒不变的需求。本次设计的文档管理系统有管理员和用户两个角色。管理员功能有论坛管理&#xff0c;公告管理…

Spark-环境启动

一、概览 从start-all.sh开始捋&#xff0c;一直捋到Master、Worker的启动并建立通信 二、宏观描述 Master端 1、start-all.sh调用start-master.sh启动Master 2、执行org.apache.spark.deploy.master.Master中main方法 3、通过工厂模式创建RpcEnv子类NettyRpcEnv a、创建…

【Vue3】路由Params传参

【Vue3】路由Params传参 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日…

【Redis】Linux CentOS Redis 的安装—(一)

Redis 一、获取源二、解压编译 一、获取源 //redis-stable是最新稳定版 wget https://download.redis.io/redis-stable.tar.gz二、解压编译 //我指定目录/app tar -xzvf redis-stable.tar.gz -C /appcd /app/redis-stablemake && make install##三 、修改配置启动 …

PyTorch 基础学习(5)- 神经网络

系列文章&#xff1a; PyTorch 基础学习&#xff08;1&#xff09; - 快速入门 PyTorch 基础学习&#xff08;2&#xff09;- 张量 Tensors PyTorch 基础学习&#xff08;3&#xff09; - 张量的数学操作 PyTorch 基础学习&#xff08;4&#xff09;- 张量的类型 PyTorch 基础学…

【阿卡迈防护分析】Vueling航空Akamai破盾实战

文章目录 1. 写在前面2. 风控分析3. 破盾实战 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

计算机毕业设计 美妆神域网站 美妆商城系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

springboot生成、响应图片验证码

我们平时经常会碰见图片验证码&#xff0c;那么在springboot中我们该怎么实现呢 我们可以使用一款开源的验证码生成工具EasyCaptcha&#xff0c;其支持多种类型的验证码&#xff0c;例如gif、中文、算术等&#xff0c;并且简单易用&#xff0c;具体内容可参考其官方文档。 效果…

【三维重建】SpotlessSplats:去除瞬态干扰物的三维高斯喷溅(3DGS)

代码&#xff1a;https://spotlesssplats.github.io 论文&#xff1a;https://arxiv.org/pdf/2406.20055 来源&#xff1a;DeepMind&#xff0c;多伦多大学&#xff0c;斯坦福大学&#xff0c;西蒙弗雷泽大学 提示&#xff1a;关注B站【方矩实验室】&#xff0c;查看视频讲解…

11.怎么做好一个动态标签页

效果 步骤 1.在Elementui找一个标签页组件 复制粘贴到代码 2.将他写活 将很多页面需要用的方法和变量写入store editableTabsValue: 2,editableTabs: [{title: 首页,name: index,},],addTab(state, tab) {if (state.editableTabs.findIndex(item > item.title tab.titl…

LVGL系列2--linux + lvglv8 + vscode 移植

LVGL系列 一、LVGL移植 LVGL系列1–AT32移植LVGL_V8具体步骤 LVGL系列2–linux lvglv8 vscode 移植 二、输入设备 LVGL系列3–纯物理(外部)按键&#xff0c;数字键盘控制控件 文章目录 LVGL系列一、LVGL移植二、输入设备 一、新建文件夹并克隆源码官方仓库 7.11.0官方仓库…

【AI/算法类】OPPO 2025届秋招笔试题(B卷)

目录 1. 第一题2. 第二题3. 第三题 ⏰ 时间&#xff1a;2024/08/10 &#x1f504; 输入输出&#xff1a;ACM格式 ⏳ 时长&#xff1a;2h 本试卷还有选择题部分&#xff0c;但这部分比较简单就不再展示。 1. 第一题 小O有一个正整数 x x x&#xff0c;他想知道&#xff0c;第…

抽卡机小程序,开启全新拆卡乐趣

近段时间&#xff0c;盲盒卡牌市场异常火爆&#xff0c;最近爆火的“小马宝莉”系列卡牌就深受消费者的喜爱&#xff0c;受到了广泛关注&#xff0c;同时也推动了卡牌市场的快速发展&#xff01;盲盒卡牌拥有隐藏款卡牌和限量款卡牌&#xff0c;具有非常大的收藏价值&#xff0…

使用Java调用Apache commons-text求解字符串相似性实战

目录 前言 一、字符串距离的几种计算方法 1、Levenshtein 距离 2、Overlap Coefficient计算 3、Q-gram Matching 4、余弦相似性计算 二、基于余弦相似性的基地名称对比 1、加载百科中的基地信息列表 2、设置忽略词列表 3、将数据库地名和Excel进行对比 三、总结 前言…

从力扣中等+困难题+表白HTML测试 -- 文心快码(Baidu Comate)

0 写在前面 官网地址&#xff1a;Baidu Comate Step1 打开文心快码&#xff08;Baidu Comate&#xff09;官网&#xff0c;点击「免费使用」/「下载安装」 Step2 可以根据官网步骤快速唤起VS Code&#xff1b; 也可以直接在VS Code、Visual Studio扩展管理搜索“文心快码”/…

如何用OceanBase实现HBase架构升级

随着数据量的爆炸性增长&#xff0c;特别是半结构化和非结构化数据的涌现&#xff0c;传统关系型数据库如 MySQL 遭遇了前所未有的挑战。这一背景下&#xff0c;为非结构化数据管理而生的 NoSQL 数据库&#xff0c;以及旨在解决海量数据存储难题的分布式技术应运而生&#xff0…