QT 串口上位机读卡显示
目录
一. QT创建工程
二. 软件更换图标
三. QT打包
一. QT创建工程
文件新建,选择创建一个桌面QT。

重命名RFID,并选择工程保存路径

RFID.pro
QT += core gui serialport
#串行串口greaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = RFID
TEMPLATE = appSOURCES += main.cpp\mainwindow.cppHEADERS += mainwindow.hFORMS += mainwindow.ui
#使用C++11
CONFIG += c++11
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSerialPort>
#include <QByteArray>
#include <QTimer>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECT // Qt 中的宏,支持信号和槽机制public:// 构造函数,初始化 MainWindow 对象explicit MainWindow(QWidget *parent = nullptr);// 析构函数,用于销毁 MainWindow 对象,防止内存泄漏~MainWindow();private slots:// 当发送按钮被点击时执行的槽函数,用于向串口发送数据void on_sendButton_clicked(); // 读取串口接收到的数据,当串口有数据可读时调用void readData(); // 打开或关闭串口,响应打开按钮的点击事件void on_openButton_clicked(); // 扫描可用的串口端口列表,并在界面中显示void scanAvailablePorts(); private:Ui::MainWindow *ui; // UI 界面类的指针,用于访问 UI 中的控件QSerialPort *serial; // 串口对象的指针,处理与串口相关的通信操作QTimer *scanTimer; // 定时器指针,用于定时扫描可用的串口// 配置串口参数(如波特率、数据位、停止位等)void configureSerialPort(); // 更新状态栏的消息,提示用户当前串口的状态void updateStatusMessage();
};#endif // MAINWINDOW_H
main.cpp
#include "mainwindow.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPortInfo>
#include <QByteArray>
#include <QDebug>
#include <QString>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow),serial(new QSerialPort(this)),scanTimer(new QTimer(this)) // 初始化定时器
{ui->setupUi(this);// 设置窗口标题 左上角的setWindowTitle("白卡写卡软件");// 扫描可用的串口connect(scanTimer, &QTimer::timeout, this, &MainWindow::scanAvailablePorts);scanTimer->start(1000); // 每秒扫描一次connect(ui->sendButton, &QPushButton::clicked, this, &MainWindow::on_sendButton_clicked);connect(ui->openButton, &QPushButton::clicked, this, &MainWindow::on_openButton_clicked);connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);// 初次扫描端口scanAvailablePorts();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::scanAvailablePorts()
{QString currentPortName = ui->portComboBox->currentText();bool currentPortStillAvailable = false;ui->portComboBox->clear();const auto serialPortInfos = QSerialPortInfo::availablePorts();for (const QSerialPortInfo &serialPortInfo : serialPortInfos) {ui->portComboBox->addItem(serialPortInfo.portName());if (serialPortInfo.portName() == currentPortName) {currentPortStillAvailable = true;}}// 如果当前选择的端口仍然可用,则重新选择它if (currentPortStillAvailable) {ui->portComboBox->setCurrentText(currentPortName);} else if (ui->portComboBox->count() > 0) {ui->portComboBox->setCurrentIndex(0);}updateStatusMessage();
}void MainWindow::configureSerialPort()
{if (serial->isOpen()) {serial->close();}QString portName = ui->portComboBox->currentText();serial->setPortName(portName);serial->setBaudRate(QSerialPort::Baud115200); // 设置波特率为 115200serial->setDataBits(QSerialPort::Data8);serial->setParity(QSerialPort::NoParity);serial->setStopBits(QSerialPort::OneStop);serial->setFlowControl(QSerialPort::NoFlowControl);if (serial->open(QIODevice::ReadWrite)) {ui->statusBar->showMessage("串口打开: " + portName);scanTimer->stop(); // 成功打开串口后停止扫描} else {ui->statusBar->showMessage("无法打开串口: " + portName);}
}void MainWindow::on_openButton_clicked()
{configureSerialPort();updateStatusMessage();
}void MainWindow::updateStatusMessage()
{if (serial->isOpen()) {ui->statusBar->showMessage("串口打开: " + ui->portComboBox->currentText());} else {ui->statusBar->showMessage("串口未连接");}
}void MainWindow::on_sendButton_clicked()
{if (!serial->isOpen()) {ui->statusBar->showMessage("串口未连接");return;}// 获取用户输入并转换为字节数组QString inputText = ui->inputLineEdit->text();// 将十进制字符串转换为整数bool ok;int decimalValue = inputText.toInt(&ok);if (!ok) {qDebug() << "Invalid decimal input";return;}// 确保整数值在 0 到 255 之间,因为我们要将其表示为一个字节if (decimalValue < 0 || decimalValue > 255) {qDebug() << "Decimal value out of range (0-255)";return;}// 创建并初始化 QByteArrayQByteArray data(11, 0); // 预先分配 11 个字节并初始化为 0data[0] = static_cast<char>(0x40);data[1] = static_cast<char>(0xA9);data[2] = static_cast<char>(0x00);data[3] = static_cast<char>(0x04);data[4] = static_cast<char>(0x00);data[5] = static_cast<char>(0x00);data[6] = static_cast<char>(0x00);data[7] = static_cast<char>(0x00); // 预留一个位置data[8] = static_cast<char>(0x00);data[9] = static_cast<char>(0x00);data[10] = static_cast<char>(0x0D);// 将整数转换为十六进制字节char hexByte = static_cast<char>(decimalValue);// 将该字节放入 QByteArray 的第八个位置(索引 7)data[7] = hexByte;// 发送数据serial->write(data);
}void MainWindow::readData()
{if (!serial->isOpen()) {ui->statusBar->showMessage("串口未连接");return;}QByteArray receivedData = serial->readAll();// 显示接收到的全部数据(十六进制格式)ui->receivedDataTextEdit->append(receivedData.toHex().toUpper());// 获取第13个字节的数据并显示在特定窗口if (receivedData.size() >= 13) {// 获取第13个字节的数据unsigned char byte13 = static_cast<unsigned char>(receivedData[12]);// 将字节转换为十进制表示int decimalValue = static_cast<int>(byte13);// 将十进制整数转换为字符串QString decimalString = QString::number(decimalValue);// 在特定窗口中显示十进制数据ui->byte13Label->setText(decimalString);}
}
mainwindow.ui

1.选择串口的下拉框(Combo Box) : portComboBox2.打开按钮 : openButton3.写卡号输入框(Line Edit) : inputLineEdit4.写卡按钮 : sendButton5.串口数据窗口(Text Edit) : receivedDataTextEdit6.当前卡号显示 (Label): byte13Label
运行效果:

二. 软件更换图标
在工程目录新建文件夹resources

里面放ico格式的图片
iconfont-阿里巴巴矢量图标库
PNG转ICO - 在线转换图标文件

在 Qt Creator 中,右键单击项目名称并选择"添加新文件" > "Qt" > "Qt Resource File",将资源文件添加到项目中

将资源文件命名为"resources.qrc"

在 Qt Creator 中打开"resources.qrc"文件,右键单击文件并选择"添加前缀"。添加一个名称,例如"/icons"

右键单击新创建的前缀("/icons"),然后选择"添加文件",将步骤 2 中的 `.ico` 文件添加到资源文件中
更新 .pro 文件
在 Qt Creator 中打开项目的 .pro 文件。
RC_ICONS = resources/rfid.ico
三. QT打包
以 Release 方式编译生成 exe 程序:

生成的程序运行正常之后,找到项目的生成目录,比如 项目源码路径:C:\Users\Administrator\Desktop\WR\WR\RFID 。
它的项目生成目录是 C:\Users\Administrator\Desktop\WR\build-RFID-Desktop_Qt_5_4_0_MinGW_32bit-Release 。
进入这个文件夹,在进入它的子文件夹 release 里面,找到 RFID.exe,将这个exe 复制到一个新的单独的文件夹里用于发布,比如存到 C:\Users\Administrator\Desktop\WR\WR\Card 文件夹里面。
然后从开始菜单打开 Qt 命令行,

输入命令:cd C:\Users\Administrator\Desktop\WR\WR\Card
然后使用 windeployqt 工具命令:windeployqt RFID.exe

打包完成

直接可以运行

封包软件
打开Enigma Virtual Box,浏览封包的主程序

点击右下角的“文件选项”按钮,打开“文件选项”窗口,并勾选其中的“压缩文件”,如下图中红框所示。压缩后的单文件会小得多,所以建议勾选。

点击左下角的“增加”按钮,开始增加文件,如下图所示。


确认后

点击确定

执行封包

运行

这时候card路径下生成一个新的exe可以发送,也不会少包
![]()
链接: https://pan.baidu.com/s/1U9RA7MdLsOJZUqYMW3FUjg?pwd=ff5q 提取码: ff5q
相关文章:
QT 串口上位机读卡显示
目录 一. QT创建工程 二. 软件更换图标 三. QT打包 一. QT创建工程 文件新建,选择创建一个桌面QT。 重命名RFID,并选择工程保存路径 RFID.pro QT core gui serialport #串行串口greaterThan(QT_MAJOR_VERSION, 4): QT widgetsTARGET RFID TE…...
Chrome谷歌浏览器登录账号next无反应
文章目录 问题描述 我们的Chrome浏览器在更新之后,会出现登录谷歌账号的时候,当你输入你的谷歌邮箱之后,点击 n e x t next next,也就是下一步的时候,页面没有反应,也就是没有跳转到输入密码的页面。 分析 根据logs里…...
Android相关线程基础
线程基础 进程与线程 进程:可以被看做是程序的实体, 是系统进行资源分配和调度的基本单位. 线程:是操作系统调度的最小单元, 也叫轻量级进程 使用多线程的优点 可以减少程序的响应时间。如果某个操作很耗时, 能够避免陷入长时间的等待, 从而有着更好的交互性. 线程较之进…...
uniapp 如何自定义导航栏并自适应机型
如今的移动设备有各种不同的屏幕形状,如刘海屏、水滴屏等。这些异形屏会影响页面的布局,尤其是导航栏和底部栏的显示。通过获取安全区域信息,可以确保页面内容不会被异形屏的特殊区域遮挡。 在设计页面顶部导航栏时,可以根据 saf…...
Java高级Day43-类加载
117.类加载 静态和动态加载 反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载 静态加载:编译时加载相关的类,如果没有则报错,依赖性太强 动态加载:运行时加载需要的类,如果运行时不用该类…...
【LeetCode 算法笔记】155. 最小栈
目录 问题描述单个栈实现双栈实现不开辟额外空间 问题描述 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。 void push(int val) 将元素val推入堆栈。 void pop()…...
面试题 05.01. 插入
目录 一:题目: 二:代码: 三:结果: 一:题目: 给定两个整型数字 N 与 M,以及表示比特位置的 i 与 j(i < j,且从 0 位开始计算)。…...
稠密向量检索、稀疏向量检索、BM25检索三者对比
在当今的信息检索领域,随着人工智能和自然语言处理技术的发展,稠密向量检索和稀疏向量检索成为了两种主要的研究方向。稠密向量检索依托于高维空间中的向量表示,能够捕捉文档的深层语义信息,而稀疏向量检索则侧重于关键词的匹配&a…...
UEFI学习笔记(六):EDK II 模块:Libraries,DriversApplication
UEFI学习笔记(六):EDK II Modules:Libraries,Application&Drivers 一、模块(Modules)的概念1、Library模块2、Application模块3、Driver模块4、Application和Driver的区别 二、EDK II 实现U…...
详解 Pandas 的透视表函数
Pandas 的透视表函数主要为 pivot() 和 pivot_table(),主要的功能为对 DataFrame 的行和列进行重新组合来重塑数据。 一、pivot 函数 pivot 函数只能对数据进行重塑,不能进行聚合 1. 数据准备 import pandas as pddf1 pd.DataFrame({department_id: […...
基于python+django+vue的农业管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的农…...
动态内存管理之malloc,free,calloc和realloc函数
Hello,各位小伙伴们,小编在这里祝福各位中秋佳节快乐呀,今天让我们来学习一下动态内存管理吧! 引言 像我们之前在开辟一段空间的时候你可能会使用整型变量来申请一块空间,或者使用数组来申请一段连续的空间ÿ…...
Android 13 固定systemUI的状态栏为黑底白字,不能被系统应用或者三方应用修改
目录 一.背景 二.思路 三.代码流程 1.colos.xml自定义颜色 2.设置状态栏的背景颜色 3.对View进行操作 ①.对Clock(状态栏左侧的数字时钟)进行操作 ②.对电池(BatteryMeterView)进行操作 4.锁屏状态栏 5.patch汇总 一.背景 客户需求将状态栏固定成黑底白字,并且不能让系…...
【CTF Reverse】XCTF GFSJ1092 easyEZbaby_app Writeup(Android+逆向工程+Java)
easyEZbaby_app 究极简单的安卓逆向 解法 得到一个 apk 安装包。 用 jadx 打开,搜索文本 flag,加载所有。 flag 是 obj obj2,来自用户的用户名和密码。 Override // android.view.View.OnClickListenerpublic void onClick(View view) {St…...
ubuntu 22.04 ~24.04 如何修改登录背景
ubuntu 22.04 ~24.04 如何修改登录背景 背景:由于22.04 登录gdm的变更,之前的修改登录背景的方案已经无法使用。现在给大家分享新的使用方法: 1,下载如下路径的脚本: https://download.csdn.net/download/xdhyqd/89…...
Andrej Karpathy谈AI未来:自动驾驶、Transformer与人机融合
引言 在人工智能领域,Andrej Karpathy 是一个无法忽视的名字。从他早期在 OpenAI 的工作,到后来担任 Tesla 的 AI 主管,他在自动驾驶、深度学习等方面的贡献广为人知。最近,卡帕西做客了著名的播客节目 No Priors,他在…...
Vue使用query传参Boolean类型,刷新之后转换为String问题
做项目时发现第一次进入页面时传参是正常的Boolean类型,刷新之后变成了String,这是浏览器进行的一次强制转换; vue-router 传参,不管是 params 形式还是query形式传参,在页面刷新后,params 和 query 对象中…...
开源模型应用落地-qwen模型小试-调用Qwen2-VL-7B-Instruct-更清晰地看世界(一)
一、前言 学习Qwen2-VL ,为我们打开了一扇通往先进人工智能技术的大门。让我们能够深入了解当今最前沿的视觉语言模型的工作原理和强大能力。这不仅拓宽了我们的知识视野,更让我们站在科技发展的潮头,紧跟时代的步伐。 Qwen2-VL 具有卓越的图像和视频理解能力,以及多语言支…...
国学盛典 致敬先贤 《老子与道德经》纪录片研讨会在北京善品堂国学馆圆满落幕
9月10日,《老子与道德经》纪录片研讨会在北京善品堂国学馆圆满落幕。中国著名表演艺术家、曾饰演央视86版电视剧《西游记》中“孙悟空”的六小龄童先生与两百余人传统文化传播者、践行者、爱好者齐聚一堂,共同交流。本次会议由中国文化促进会福文化工作委…...
sqlgun新闻管理系统
一,打开主页 1.输入框测试回显点 -1union select 1,2,3# 出现回显点2 2.查看数据库表名 -1union select 1,database(),3# 3.查看表名 -1union select 1,2,group_concat(table_name) from information_schema.tables where table_schemasqlgunnews# 4.查看admin中…...
技术赋能B端拓客:号码核验行业的迭代与价值升级,氪迹科技法人股东号码核验系统,阶梯式价格
2026年,B端市场竞争进入白热化阶段,拓客逻辑已从“规模扩张”转向“价值深耕”,“精准、高效、低成本”成为所有拓客团队的核心追求。号码核验作为B端拓客的前置基础性环节,其服务质量直接决定线索价值、人力效能与投入回报比&…...
OpenClaw语音交互:Phi-3-mini接入麦克风输入实战
OpenClaw语音交互:Phi-3-mini接入麦克风输入实战 1. 为什么需要语音交互能力 上周我在整理电脑文件时突然想到一个问题:当我的双手被占用时(比如正在做饭或修理设备),如何让OpenClaw帮我执行任务?传统的键…...
AI命理推理实测:用专业数据集验证大模型命理能力
提到AI命理相关的评测,就不得不说之前看到的,我们团队最近也沿着这个方向做了针对性测试,不是网上那种随便给大模型发个prompt就喊“准到离谱”的营销玩法,而是用有标准答案的盲测来验证AI命理推理的真实水平。 我们的评测是怎么…...
基于Wan 3D Causal VAE(Show-o2)的模型,重新完整地分析 10分钟的视频 对应多少 vison token
可以。这次我按 Show-o2 官方 432432 配置 和 Wan 3D Causal VAE 的公开时间压缩规则,把 10B token 且全部都是 vision token 的情况重新完整算一遍。下面的“大小”我统一按 未压缩 RGB 原始数据量 来算;如果你问的是实际 JPG / PNG / MP4 落盘大小,那会随压缩格式、码率和…...
Polars 2.0插件生态爆发(2024唯一官方认证清洗套件清单)
第一章:Polars 2.0插件生态爆发(2024唯一官方认证清洗套件清单) 随着 Polars 2.0 的正式发布,其插件系统完成重大重构,首次开放官方插件注册与签名认证机制。截至 2024 年第三季度,Polars 核心团队已通过 …...
Win11Debloat开源工具:焕新Windows系统体验的极简优化指南
Win11Debloat开源工具:焕新Windows系统体验的极简优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter an…...
AI中混淆矩阵及其核心评估指标案例
AI中混淆矩阵及其核心评估指标案例...
数据仓库核心建模:星型模型与雪花模型全面对比与实战选择
数据仓库核心建模:星型模型与雪花模型全面对比与实战选择一、引言二、定义:什么是星型模型?什么是雪花模型?2.1 星型模型:定义2.2 雪花模型:定义三、结构流程图:直观对比两种模型3.1 星型模型流…...
从芯片包到破解:Keil MDK5完整安装与配置实战(附最新支持包离线导入方法)
从芯片包到破解:Keil MDK5完整安装与配置实战(附最新支持包离线导入方法) 在嵌入式开发领域,Keil MDK5作为ARM架构微控制器的主流开发环境,其安装配置的完整性与稳定性直接影响后续开发效率。本文将系统性地拆解从软件…...
实战应用:基于快马平台开发完整权限监控应用,保障用户隐私
今天想和大家分享一个非常实用的安卓应用开发实战项目——相册权限监控工具。这个项目的灵感来源于日常生活中大家对隐私保护的关注,特别是最近关于某些应用可能滥用相册权限的讨论。通过InsCode(快马)平台,我们可以快速实现一个完整的解决方案。 项目背…...
