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 

QT串口曲线显示上位机下载是一种基于QT开发的应用程序,旨在实现通过串口连接外部设备并实时显示曲线数据的功能。该上位机软件可以在电脑等终端设备上运行,并通过串口与外部设备进行通信。 首先,您需要在互联网上搜索并找到可信的QT串口曲线显示上位机下载资源。通常,开发者会将该软件上传至代码库或开发者网站上,您可以通过访问这些网站进行下载。确保选择来自可靠来源的下载链接,以避免下载到恶意软件或病毒。 下载完成后,您可以双击运行该安装程序。安装程序将会引导您完成安装过程,您可以按照提示逐步操作,直到完成整个安装过程。 安装完成后,您可以在计算机上找到并运行QT串口曲线显示上位机应用程序。打开应用程序后,您将看到一个用户友好的界面,其中包含了串口连接的设置选项、曲线显示区域以及其他功能按钮。 在设置选项中,您需要选择正确的串口号和波特率,以确保应用程序能够正确连接到外部设备。一旦设置完成,您可以点击“连接”按钮进行串口连接。 一旦连接成功,您将能够收到来自外部设备的数据,并通过曲线显示区域实时显示曲线。您可以使用应用程序提供的功能按钮,如放大、缩小、保存等,以进一步操作和分析曲线数据。 总之,QT串口曲线显示上位机是一款方便实用的软件,可帮助用户通过串口连接外部设备并实时显示曲线数据。下载安装简单方便,并具有丰富的功能和用户界面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chem4111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值