当前位置: 首页 > news >正文

基于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开发与串口通信相关的知识,并将这些技能应用到实际项目中。如果你在开发过程中遇到任何问题,欢迎在评论区交流讨论。

相关文章:

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

目录 一、前言 二、环境准备 三、创建QT串口项目 ​编辑 四、串口项目实现 1.ui界面设计 2.添加QT串口模块 3.功能实现 ①串口扫描 ②波特率、停止位等设置 ③接收数据 ④发送数据 五、最终效果 六、总结 一、前言 如果有人之前看过我文章的话应该知道&#xf…...

Mysql之视图

视图 创建语法&#xff1a;create [or replace] view 视图名称 as select * from where [with check option] 查询&#xff1a;show create view 视图名称 查看视图数据&#xff1a;select * from 视图名称 修改&#xff1a; 1&#xff0c;可以使用创建的语法更新&#xf…...

【开端】Java 分页工具类运用

一、绪论 Java系统中&#xff0c;分页查询的场景随处可见&#xff0c;本节介com.baomidou.mybatisplus.core.metadata.IPage;来分页的工具类 二、分页工具类 public class PageUtils implements Serializable { private static final long serialVersionUID 1L; /**…...

leetcode每日一题48

143.环形链表ii 快慢指针 至于入环点的计算 设链表中环外部分的长度为 a。slow 指针进入环后&#xff0c;又走了 b 的距离与 fast 相遇。此时&#xff0c;fast 指针已经走完了环的 n 圈&#xff0c;因此它走过的总距离为 an(bc)ba(n1)bnc。 任意时刻&#xff0c;fast 指针走过…...

源码工具文档手册

手册文档工具 TinaSDK开发文档&#xff1a;https://tina.100ask.net/ 开发板使用文档&#xff1a;https://allwinner-docs.100ask.net/ 教程示例 一板懂百板通&#xff1a;https://www.bilibili.com/video/BV1Nx4y1w7AF/?spm_id_from333.999.0.0 T113 LVGLUI开发&#xff1…...

hive之greatest和least函数

1、greatest函数&#xff1a; greatest(col_a, col_b, ..., col_n)比较n个column的大小&#xff0c;过滤掉null或对null值进行处理&#xff0c;当某个column中是string&#xff0c;而其他是int/double/float等时&#xff0c;返回null&#xff1b; 举例&#xff1a; select g…...

C:数组传参的本质

1、一维数组传参的本质 数组传参是指在函数调用时将数组作为参数传递给函数。 int main() {int arr[10] { 1,2,3,4,5,6,7,8,9,10 };test(arr);return 0;}数组传参只需要写数组名就可以了。注意&#xff1a;数组名是arr&#xff0c;而不是arr[10] 数组传参形参该怎么写呢&am…...

excel 2019版本的index match搜索功能

{TEXTJOIN("", TRUE, IF((sheet2!A:A"文字")*(sheet2!C:CC5), sheet2!G:G, ""))} excel单元格输入公式后&#xff1a; TEXTJOIN("", TRUE, IF((sheet2!A:A"文字")*(sheet2!C:CC5), sheet2!G:G, "")) 按CtrlShi…...

【问题解决】apache.poi 3.1.4版本升级到 5.2.3,导出文件报错版本无法解析

【问题解决】apache.poi 3.1.4版本升级到 5.2.3&#xff0c;导出文件报错无法解析 3.1.4版本代码&#xff1a; /*** 创建workbook* param inp* return* throws Exception*/public Workbook createworkbook(InputStream inp) throws Exception {if (!inp.markSupported()) {inp…...

(亲测有效)SpringBoot项目集成腾讯云COS对象存储(2)

接上文&#xff08;亲测有效&#xff09;SpringBoot项目集成腾讯云COS对象存储&#xff08;1&#xff09;-CSDN博客 目录 3、通用能力类 文件下载 测试 3、通用能力类 文件下载 官方文档介绍了2种文件下载方式。一种是直接下载 COS 的文件到后端服务器&#xff08;适合服务…...

界面优化 - QSS

目录 1、背景介绍 2、基本语法 3、QSS 设置方式 3.1 指定控件样式设置 代码示例: 子元素受到影响 3.2 全局样式设置 代码示例: 使用全局样式 代码示例: 样式的层叠特性 代码示例: 样式的优先级 3.3 从文件加载样式表 代码示例: 从文件加载全局样式 3.4 使用 Qt Desi…...

实现基于TCP协议的服务器与客户机间简单通信

服务器端程序 #include <myhead.h> #define SER_PORT 6666 //服务器端口号 #define SER_IP "192.168.2.53" //服务器ip地址 int main(int argc, char const *argv[]) { /*创建套接字 int socket(int domain, int type, int protocol);*/ …...

在uniapp中使用navigator.MediaDevices.getUserMedia()拍照并上传服务器

产品提了这样一个需求&#xff1a; 移动端拍照上传后图片不保存在用户设备上&#xff0c;试了好几种方法&#xff0c;uni-file-picker、uni.chooseImage、input type‘file’&#xff0c;安卓手机都会默认把图片保存在手机&#xff0c;于是各种查资料&#xff0c;找到了以下方法…...

PULLUP

重要提示&#xff1a;PULLUP属性已被弃用&#xff0c;应替换为PULLTYPE 财产。 PULLUP在三态输出或双向端口上应用弱逻辑高&#xff0c;以防止 它从漂浮。PULLUP属性保证逻辑高电平&#xff0c;以允许三态网络 以避免在不被驱动时漂浮。 输入缓冲器&#xff08;如IBUF&#xff…...

【无标题】乐天HIQ壁挂炉使用

这里写自定义目录标题 1.按键①&#xff1a; 按一下&#xff0c;小液晶显示的温度是所设定的供暖温度&#xff1b; 按二下&#xff0c;小液晶显示的温度是所设定的生活热水温度&#xff1b; 按三下&#xff0c;小液晶显示的温度是所设定的室内温度&#xff1b; 如果忘记按几下的…...

使用Python编写AI程序,让机器变得更智能

人工智能&#xff08;AI&#xff09;是当今科技领域最热门的话题之一。随着Python编程语言的逐渐流行&#xff0c;它已经成为许多人工智能编程的首选语言。本文将介绍如何使用Python编写AI程序&#xff0c;让机器变得更智能。 首先&#xff0c;Python提供了大量的AI库和工具&a…...

VScode + PlatformIO 和 Keil 开发 STM32

以前经常使用 KEIL 写 STM32 的代码&#xff0c;自从使用 VScode 写 ESP32 后感觉 KEIL 的开发环境不美观不智能了&#xff0c;后面学习了 VScode 开发 STM32 。 使用过程中发现 串口重定向在 KEIL 中可以用&#xff0c;搬到 VScode 后不能用&#xff0c;不用勾选 Use Micro LI…...

PostgreSQL 练习 ---- psql 新增连接参数

目标 添加一个连接参数&#xff0c;默认为 false 。当 psql 连接时&#xff0c;若该连接参数非 “true” 时&#xff0c;用户 “u1“ 对表对象无操作权限&#xff0c;包括自己拥有的表。 连接机制简介 连接过程如下所述&#xff1a; 客户端初始化一个空连接&#xff0c;设置…...

pdf翻译软件哪个好用?多语言轻松转

想知道怎么用pdf翻译器在线翻译吗&#xff1f;无需复杂操作&#xff0c;一键即可解锁语言障碍。 在这个全球化日益加深的时代&#xff0c;掌握pdf文件的快速翻译技巧尤为重要。 无论是学习、工作还是国际交流&#xff0c;以下4个免费pdf翻译技巧都将是你不可或缺的得力助手。…...

培训第三十天(ansible模块的使用)

上午 ansible是⼀种由Python开发的⾃动化运维⼯具&#xff0c;集合了众多运维⼯ 具&#xff08;puppet、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量 系统配置、批量程序部署、批量运⾏命令等功能。 1、学习ansible的使用 ansible 主机ip|域名|组…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...