QT 串口上位机读卡显示

目录

一.   QT创建工程

二.   软件更换图标 

三.   QT打包


一.   QT创建工程

文件新建,选择创建一个桌面QT。

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

 RFID.pro

QT       += core gui serialport
#串行串口

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = RFID
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += 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);  // 设置波特率为 115200
    serial->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;
    }

    // 创建并初始化 QByteArray
    QByteArray data(11, 0); // 预先分配 11 个字节并初始化为 0
    data[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) : portComboBox

2.打开按钮 : openButton

3.写卡号输入框(Line Edit) : inputLineEdit

4.写卡按钮 : sendButton

5.串口数据窗口(Text Edit) : receivedDataTextEdit

6.当前卡号显示 (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 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLMs之SWIFT:SWIFT的简介、安装和使用方法、案例应用之详细攻略

LLMs之SWIFT&#xff1a;SWIFT的简介、安装和使用方法、案例应用之详细攻略 目录 SWIFT的简介 新闻 &#x1f6e0;️ 安装 &#x1f680; 快速开始 Web-UI 训练 训练脚本 支持的训练过程 单卡训练 模型并行训练 数据并行训练 Deepspeed训练 多机多卡 阿里云-DLC多…

面试官:讲一讲Spring MVC源码解析

好看的皮囊千篇一律、有趣的灵魂万里挑一 文章持续更新&#xff0c;可以微信搜索【小奇JAVA面试】第一时间阅读&#xff0c;回复【资料】获取福利&#xff0c;回复【项目】获取项目源码&#xff0c;回复【简历模板】获取简历模板&#xff0c;回复【学习路线图】获取学习路线图。…

【C++】——继承详解

目录 1、继承的概念与意义 2、继承的使用 2.1继承的定义及语法 2.2基类与派生类间的转换 2.3继承中的作用域 2.4派生类的默认成员函数 <1>构造函数 <2>拷贝构造函数 <3>赋值重载函数 <4析构函数 <5>总结 3、继承与友元 4、继承与静态变…

Linux(CentOS8)服务器安装RabbitMQ

我安装了很久都没有成功, 各种问题, 每次的异常都不一样, 现将成功安装过程做个总结 安装前工作 确保已经安装了一些基础工具和组件库 下载安装包 https://www.erlang.org/patches/otp-24.3.4.5 https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.15/ra…

C/C++实现植物大战僵尸(PVZ)(打地鼠版)

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 游戏…

Linux中的简单命令2

一.echo指令 echo的作用是显式文本内容 #echo ‘字符串’ #echo “字符串” echo会将后面的内容当作字符串直接打印在屏幕上&#xff0c;后面的内容需要用单引号或者双引号括起来 注意&#xff1a;echo会自动在字符串后面加上一个换行符。 可以与printf进行对比&#xff1a; …

常耀斌:AI赋能企业数字化转型(清华社发行)

新书地址&#xff1a; 清华出版社&#xff1a;清华大学出版社-图书详情-《AI赋能企业数字化转型》 京东&#xff1a;《AI赋能企业数字化转型 常耀斌 清华大学出版社 9787302669081》【摘要 书评 试读】- 京东图书 内容简介&#xff1a; 在数字经济时代&#xff0c;企业发…

【Linux:命名管道】

命名管道原理&#xff1a; 每一个进程都有独立的struct files_struct和struct file文件属性集合和操作集只存储一份&#xff0c;因为属性集合和操作集每个文件都差不多一样两个进程读写都在同一个内核缓冲区就可以实现进程间通信 数据写入缓冲区后还需要将数据刷新到磁盘中&…

springboot+mybatis+mysql仿百度网盘系统2.0

springbootmybatismysql仿百度网盘系统2.0 一、系统介绍二、功能展示1.用户登陆2.主页3.全部文件4.文件上传5.文件分享6.文件分类 三、其它1.其他系统实现 一、系统介绍 系统主要功能&#xff1a; 普通用户&#xff1a;用户登陆、主页、全部文件、上传文件、文件分类、文件分部…

什么是上拉,下拉?

上拉就是将引脚通过一个电阻连接到电源&#xff0c;作用&#xff1a;1.使IO口的不确定电平稳定在高点平&#xff0c;2、为了增加IO口拉电流的能力。 下拉就是将引脚通过一个电阻与GND相连&#xff0c;作用&#xff1a;1.从器件输出电流 2.当IO口为输入状态时&#xff0c;引脚的…

[git] MacBook 安装git

文章目录 1.Mac Git 安装2. 开发者工具安装 CommandLineTools安装完成&#xff0c;错误解决 3. git 账户配置账户设置生成秘钥git 或者 gitee 仓库添加公钥查看全局账户命令多账户设置config文件测试连接clone到本地 1.Mac Git 安装 Mac一般自带Git工具&#xff0c;也就是说已…

yolov5明厨亮灶检测系统,厨师帽-口罩检测,带pyqt界面-可检测图片和视频,支持中文标签,检测接口已封装好并优化,代码可读性强!

明厨亮灶检测系统是一个专门用于餐饮业厨房安全监管的智能系统。该系统结合了先进的计算机视觉技术&#xff0c;尤其是使用YOLOv5模型进行厨师帽和口罩的实时检测&#xff0c;并通过PyQt5构建了一个用户友好的图形界面。该系统不仅能够检测图片和视频中的目标&#xff0c;而且支…

仪表盘检测系统源码分享

仪表盘检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Visio…

C++初阶大全

目录 一.命名空间 1.命名空间定义 2.命名空间使用 二.C输入&输出 三.缺省参数 四. 函数重载 五.引用 1.常引用 2.传值、传引用效率比较 3.引用和指针的区别 4.引用和指针的不同点: 小知识点: 六.内联函数 七.auto关键字(C11) 1.auto的使用细则 八.基于范围…

Rust练手项目,写个有趣的小工具定时从一言网获取一段有趣的话并推送通知

Rust练手项目&#xff0c;写个有趣的小工具 代码 继续练习Rust, 写个小工具定时从一言网获取一段有趣的话并提示&#xff0c;如下 练习以下Rust点 并发编程 Mutex, Arc指针使用HTTP请求Windows Gui 代码 Cargo.toml [package] name "funny_word" edition "20…

vscode中如何配置c/c++环境

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;一、准备工作二、安装 VSCode 插件三、配置 VSCode1. 配置编译任务&#xff08;tasks.json&#xff09;2. 配置调试器&#xff08;launch.json&#xff09; 四、运行和调…

数据结构(Day14)

一、学习内容 结构体 概念 引入&#xff1a;定义整数赋值为10 int a10; 定义小数赋值为3.14 float b3.14; 定义5个整数并赋值 int arr[5] {1 , 2 , 3 , 4 ,5}; 定义一个学生并赋值学号姓名成绩 定义一个雪糕并赋值名称产地单价 问题&#xff1a;没有学生、雪糕 数据类型 解决&…

【C/C++】程序的构建(编译)过程概述

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:C_小米里的大麦的博客-CSDN博客 &#x1f381;代码托管:C: 探索C编程精髓&#xff0c;打造高效代码仓库 (gitee.com) ⚙️操作环境:Visual Studio 2022 目录 一、前言 二、预处理&#xff08;Preprocessi…

C# USB通信技术(通过LibUsbDotNet库)

文章目录 1.下载LibusbDotNet库2.引入命名空间3. 实例化USB设备4.发送数据5.关闭连接 1.下载LibusbDotNet库 右击项目选择管理NuGet程序包在弹出的界面中搜索LibusbDotNet&#xff0c;然后下载安装。 2.引入命名空间 using LibUsbDotNet; using LibUsbDotNet.Main;3. 实例化…

MoneyPrinterTurbo 安装使用流程

项目地址&#xff1a; https://github.com/harry0703/MoneyPrinterTurbo 开发环境&#xff1a;mac 1 git 下载 # 下载代码到本地 git clone https://github.com/harry0703/MoneyPrinterTurbo.git cd MoneyPrinterTurbo2 docker 配源 在 docker 安装目录执行以下命令显示隐藏…