Files
VX5_KRO_GearPump/docs/项目架构说明文档.md
T
2026-07-30 11:24:14 +08:00

721 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# QtUI 韩国 喷码机项目架构说明文档
> **版本**: V6.7.5
> **目标平台**: ARM Linux (全志H618) / x86 (模拟调试)
> **Qt 版本**: Qt 5.x (ARM) / Qt 5.x (x86)
> **屏幕分辨率**: 800x600
> **文档最后更新日期**: 2026-07-23
---
## 目录
1. [项目概述](#1-项目概述)
2. [技术栈](#2-技术栈)
3. [整体架构](#3-整体架构)
4. [目录结构](#4-目录结构)
5. [核心模块详解](#5-核心模块详解)
6. [场景与打印渲染系统](#6-场景与打印渲染系统)
7. [数据流与通信机制](#7-数据流与通信机制)
8. [RFID刷卡模块](#8-rfid刷卡模块)
9. [编译构建系统](#9-编译构建系统)
10. [关键配置与宏定义](#10-关键配置与宏定义)
11. [上手指南](#11-上手指南)
---
## 1. 项目概述
本项目是一个**工业喷码机(CIJ,Continuous Ink Jet)的上位机控制系统**,运行在嵌入式ARM Linux平台上。软件通过串口与FPGA和STM32两块下位机硬件通信,实现喷码内容的编辑、预览、打印控制、设备状态监控、系统参数管理等功能。
### 核心功能
- **喷码内容编辑**: 支持文本、日期、计数器、图片、条形码(一维码)、二维码(QR/DataMatrix)等图元
- **打印控制**: 支持时延触发、电眼触发、同步器触发、电眼+同步器等多种触发模式
- **设备管理**: 墨路控制(阀门、泵、加热器)、粘度检测、相位检测、高压控制
- **系统管理**: 参数配置、FPGA/STM32固件升级、软件更新、日志管理
- **文件管理**: 作业文件的创建、保存、导入、导出(U盘)
- **RFID刷卡**: 墨水/溶剂/保养卡的身份验证与消耗管理
---
## 2. 技术栈
| 类别 | 技术 |
|------|------|
| 框架 | Qt 5.x (ARM) / Qt 5.x (x86) |
| 语言 | C++ (C++11),部分C |
| 构建工具 | qmake |
| UI设计 | Qt Designer (.ui文件) |
| 序列化 | XML (作业文件) |
| 通信 | QSerialPort (RS232/RS485) |
| 网络 | Qt Network (WiFi) |
| 条码生成 | C语言库 (BarCode目录) |
| 二维码生成 | C语言库 (QtQREnCode目录) |
| DataMatrix | C++库 (Matrix目录) |
| Modbus | 开源FreeModbus库 |
| 加密 | SM3/SM4 国密算法 |
| 日志 | 自定义Logger框架 |
---
## 3. 整体架构
项目采用**分层架构**,自上而下分为:
```
┌─────────────────────────────────────────────────────────┐
│ UI 表现层 │
│ InkJetPrinter (主窗口) + MainWidget (打印主界面) │
│ 各功能页面: SystemManage, SystemSetting, LogInfo, ... │
│ 场景编辑器: TestPrintWidget, PicScene │
├─────────────────────────────────────────────────────────┤
│ 业务逻辑层 │
│ SysPara (系统参数管理) │
│ DevOp (设备操作) │
│ RunTimeCtrl (运行时间统计) │
│ RFIDManager (刷卡管理) │
├─────────────────────────────────────────────────────────┤
│ 通信层 │
│ Serial (串口通信封装) │
│ Modbus (Modbus协议) │
├─────────────────────────────────────────────────────────┤
│ 硬件抽象层 │
│ FPGA (喷印控制、充电电压、相位检测) │
│ STM32 (墨路控制、传感器采集) │
│ RFID读卡器 (IC卡读写) │
└─────────────────────────────────────────────────────────┘
```
### 模块依赖关系图
```
InkJetPrinter (顶层窗口)
├── MainWidget (打印主界面)
│ ├── generatePrintContent (打印文件载入预览)
│ ├── FileManageWidget (文件管理)
│ ├── PrintTextDisplay (打印预览)
| └── 其他
├── TestPrintWidget (编辑界面)
│ ├── PicScene (场景内容容器)
│ ├── ItemEditor (文本图元编辑)
│ ├── ImageLoader (图片图元加载)
│ ├── BarcodeEditor (条码图元编辑)
| ├── DateVarSet (日期变量设置)
│ ├── CounterVarSet (计数器图元设置)
| └── ScheduleShiftsEditor (班次编辑)
├── SystemManage (系统管理)
├── SystemSetting (系统设置)
├── SystemUpdate (系统升级)
├── PrintSetting (打印设置)
├── MainInstruction (主指令)
├── LogInfo (日志信息)
├── OtherInfo (其他信息)
└── DialogFileOperation (打印文件选择操作)
SysPara (系统参数,贯穿所有模块)
Serial (串口通信,连接FPGA和STM32)
RFIDManager (RFID刷卡管理)
RunTimeCtrl (运行时间控制)
```
---
## 4. 目录结构
```
项目根目录/
├── QtUI.pro # 项目文件 (qmake)
├── main.cpp # 程序入口
├── mainwidget.h/cpp # 打印主界面 (MainWidget)
├── InkJetPrinter.h/cpp # 顶层主窗口
├── Public.h/cpp # 公共工具类
├── SysPara.h/cpp # 系统参数管理 (核心)
├── DevOp.h/cpp # 设备操作 (FPGA寄存器读写)
├── myinclude.h # 全局宏定义、枚举
├── VerBVersion.h # 版本号定义
├── dump.h/cpp # 崩溃信号处理
├── runtimectrl.h/cpp # 运行时间统计
│
├── scene/ # 场景(喷码内容)编辑系统
│ ├── picscene.h/cpp # 场景类 (QGraphicsScene)
│ ├── myview.h/cpp # 视图类 (QGraphicsView)
│ ├── PicSceneLoader.h/cpp # 场景XML加载/保存
│ ├── pictextitem.h/cpp # 文本图元
│ ├── PicDateItem.h/cpp # 日期图元
│ ├── PicImageItem.h/cpp # 图片图元
│ ├── PicCounterItem.h/cpp # 计数器图元
│ ├── PicScheduleShiftItem.h/cpp # 班次图元
│ ├── piccodeitem.h/cpp # 条码/二维码图元
│ ├── ViewModels.h/cpp # 视图模型 (数据结构)
│ ├── ItemCommon.h/cpp # 图元工具函数
│ ├── ItemGeneralSettings.* # 图元通用设置
│ ├── BarcodeEditor.* # 条码编辑器
│ ├── CounterEditor.* # 计数器编辑器
│ ├── DateFormatEditor.* # 日期格式编辑器
│ ├── DateReplaceEditor.* # 日期替换编辑器
│ ├── ScheduleShiftsEditor.* # 班次编辑器
│ ├── DlgBarcodeFormat.* # 条码格式对话框
│ └── DlgQrcodeFormat.* # 二维码格式对话框
│
├── rfid/ # RFID刷卡模块
│ ├── rfidmanager.h/cpp # 刷卡管理核心
│ ├── rfidfunction.h/cpp # 刷卡功能函数
│ ├── sm3.h/cpp # SM3 国密哈希
│ └── sm4.h/cpp # SM4 国密加密
│
├── Serial/ # 串口通信封装
│ └── serial.h/cpp # 串口封装 (FPGA/STM32双通道)
│
├── fileManage/ # 文件管理
│ ├── FileManageWidget.* # 文件管理界面
│ └── UDiskComboBox.* # U盘检测与文件列表
│
├── modbus/ # Modbus协议
│ ├── modbus/ # FreeModbus库
│ ├── port/ # 移植层
│ ├── modbusserial.* # Modbus串口
│ └── modbustcp.* # Modbus TCP
│
├── Log/ # 日志框架
│ ├── logger.h/cpp # 日志基类
│ ├── filelogger.h/cpp # 文件日志
│ ├── logmessage.h/cpp # 日志消息
│ └── logglobal.h # 日志全局宏
│
├── BarCode/ # 一维条码生成库 (C)
│ ├── barcode.h # 条码头文件
│ ├── code128.c/code39.c/ # 各类型条码实现
│ └── ...
│
├── QtQREnCode/ # 二维码生成库 (C)
│ ├── qrencode.h/c # QR码生成
│ └── ...
│
├── Matrix/ # DataMatrix码生成库 (C++)
│ ├── dm200.cpp # DataMatrix实现
│ └── ...
│
├── image.qrc # Qt资源文件
├── *.ts # 多语言翻译文件
│
├── 0/ ~ 101/ # 字库图片资源 (计数器图元 数字占位图)
│ └── image/
│ └── digitalWidth*.bmp
│
└── conf/ # 运行时配置目录 (部署后)
├── sysPara.bin # 系统参数二进制文件
├── config.ini # 日志配置
└── ...
```
---
## 5. 核心模块详解
### 5.1 程序入口 (main.cpp)
[main.cpp](../main.cpp#L67)
程序启动流程:
1. 读取键盘类型配置(多语言键盘/普通键盘)
2. 创建 QApplication,配置日志系统 (FileLogger)
3. 加载字体和应用级样式
4. 根据语言配置加载对应翻译文件 (.qm)
5. 创建 MyInputMethod(自定义输入法)
6. 创建 InkJetPrinter 主窗口并显示
### 5.2 主窗口 (InkJetPrinter)
[InkJetPrinter.h](../InkJetPrinter.h) | [InkJetPrinter.cpp](../InkJetPrinter.cpp)
**职责**: 顶层窗口,管理所有子页面和核心业务流程。
**关键成员**:
- `m_StackedWidget` - 页面容器,通过索引切换不同功能页面
- `m_MainWidget` - 打印主界面(首页)
- `m_TestPrintWidget` - 编辑界面
- `serialFPGA` / `serialSTM32` - 两个独立串口线程,分别与FPGA和STM32通信
- `ctrl_runTime` - 运行时间控制器
- `manager_rfid` - RFID刷卡管理器
**核心定时器**:
- `m_Timer` - 主定时器 (10ms),处理设备状态轮询、自动控制
- `viscosity_timer` - 粘度检测定时器 (1s)
**设备自动控制**:
- `autoControlValvePump()` - 阀门/泵自动控制
- `pressureAdj()` - 压力自动调节(PID算法)
- `autoControlHeater()` - 加热器自动控制
- `detectAndcontrolReclaimTank()` - 回收槽检测与控制
### 5.3 打印主界面 (MainWidget)
[mainwidget.h](../mainwidget.h) | [mainwidget.cpp](../mainwidget.cpp)
**职责**: 打印操作的主界面,包含打印预览、打印控制、文件管理。
**关键功能**:
- `generatePrintContent()` - 将场景渲染为打印数据并写入缓冲区待发送至FPGA
- `onPreviewScene` - 场景数据转为FPGA点阵数据,解析场景内容生成计数器字模及其它控制信息
- `variableItemsUpdate()` - 更新动态图元(日期、轮班、条形码/二维码等)并写入缓冲区
- `SendPrintDataToFpga()` - 通过串口向FPGA发送打印内容数据
**页面切换**:
- 通过底部导航按钮(编辑、新增、主界面、管理、消息)切换子页面
- 使用信号槽 `sendButtonClickedSignal(int)` 通知 InkJetPrinter 切换页面
### 5.4 系统参数管理 (SysPara)
[SysPara.h](../SysPara.h)
**职责**: 管理所有系统参数,是系统的数据中枢。所有模块通过 SysPara 读写参数。
**核心数据结构**:
- `calandar_and_dat_t` - 日历/计数器数据(发送给FPGA)
- `sysPara_t` - 系统参数设定
- `sysStatus_t` - 系统状态结构体
- `vars_t` - 变量类型参数设定
- `stepPrint_t` - 分段打印设定
- `alterPrint_t` - 交替打印设定
- `Cnt1ByGroup_t` - 分段计米设定
- `PrintSettingModel` - 打印设置模型(跟随作业文件保存)
- `voltePara_t` - 旧的 FPGA 墨点充电参数集结构体,用于 67 版本 FPGA
- `voltePara_t_25Dots` - 目前常用的 72 版本 FPGA 所对应的墨点充电数据集结构
- `voltePara_t_No73` - 96K 40um 喷嘴专用的FPGA墨点充电数据集结构体,专用于73版本(F8.2.1)
**参数持久化**:
- 二进制文件: `PARA_ROOT_DIR/sysPara.bin` - 对于系统参数的直接二进制保存
- XML文件: `PARA_ROOT_DIR/defPrintSet.xml` - 默认打印设置保存,新建文件时使用此配置,此配置也可通过[MainInstruction](../MainInstruction.cpp#L25) 打开默认打印设置的设置窗口(实际是复用PrintSetting窗口)。
### 5.5 设备操作 (DevOp)
[DevOp.h](../DevOp.h)
**职责**: 封装FPGA寄存器的读写操作,提供设备控制的高层接口。
**关键操作**:
- 阀门控制: `controlInkValve()`, `controlMixValve()`, `controlReleaseValve()`
- 泵控制: `WriteMoterPump()`
- 电压控制: DAC表读写 (`DAC_TABLE_ADDR`, `MATCH_*_DAC_TABLE_ADDR`)
- 打印控制: 启停、回收槽开关、故障恢复
- 计数器读写: 产品计数、同步计数
**FPGA地址空间**:
通信地址与定义位于[连续墨点喷码机通信协议](连续墨点喷码机通信地址.xlsx)
### 5.6 串口通信 (Serial)
[Serial/serial.h](../Serial/serial.h) | [Serial/serial.cpp](../Serial/serial.cpp)
**职责**: 封装与FPGA和STM32的串口通信。
**设计特点**:
- 支持双通道(FPGA和STM32各自独立串口)
- 使用消息队列管理发送数据
- CRC16校验保证数据完整性
- 支持STM32固件升级(IAP协议)
- 运行在独立QThread中,不阻塞UI
**通信协议**:
- 自定义帧格式:命令 + 地址 + 数据 + CRC16
- 发送队列: `queueFPGA` / `queue`
- 接收解析: 通过信号槽分发到上层(`receivedFromFPGA` / `receivedFromSTM32`)
### 5.7 日志系统 (Log)
#### 5.7.1 基于LogInfo的用户日志系统
**主要类**:
- `LogInfo` - 用户日志的核心类,提供日志记录、显示和保存功能,跟踪用户操作和系统事件。
#### 5.7.2 基于QDebug的日志系统
**职责**: 提供程序运行时的日志记录功能,用于开发调试和问题排查。
**类层次**:
- `Logger` - 日志基类,定义日志格式、级别过滤
- `FileLogger` - 文件日志实现,支持缓冲区批量写入
- `LogMessage` - 日志消息封装
**使用方式**:
```cpp
qInfo() << "message"; // 信息日志
qWarning() << "warning"; // 警告日志
qCritical() << "error"; // 错误日志
```
### 5.8 运行时间统计 (RunTimeCtrl)
[RunTimeCtrl](../runtimectrl.h)
**职责**: 统计软件运行时长,用于设备保养提醒。
**功能**:
- `getElapsedSeconds()` - 获取本次运行时间
- `getTotalSeconds()` - 获取总运行时间
- `sig_alertTimeout()` - 保养提醒信号
- `sig_updateTimeoutDay()` - 维护到期提醒
---
## 6. 场景与打印渲染系统
### 6.1 架构概述
场景系统基于 Qt Graphics View 框架,用于编辑和预览喷码内容。
```
PicScene (QGraphicsScene) # 场景,管理所有图元
├── 图元基类
│ ├── PicTextItem # 普通文本
│ ├── PicDateItem # 日期变量 (yyyy-MM-dd HH:mm:ss...)
│ ├── PicCounterItem # 计数器 (可变数字)
│ ├── PicImageItem # 图片 (Logo)
│ ├── PicCodeItem # 条码/二维码
│ └── PicScheduleShiftItem # 班次 (班次代码替换)
│
├── 图元编辑器
│ ├── ItemEditor # 普通文本编辑器
│ ├── DateVarSet # 日期变量编辑器
│ ├── CounterCarSet # 计数器编辑器
│ ├── ImageLoader # 图片读取器
│ ├── BarcodeEditor # 条码/二维码编辑器
│ └── ScheduleShiftsEditor # 班次 (班次代码替换)编辑器
│
├── 图元模型
│ ├── ItemEditor # 普通文本编辑器
│ ├── DateVarSet # 日期变量编辑器
│ ├── CounterCarSet # 计数器编辑器
│ ├── ImageLoader # 图片读取器
│ ├── BarcodeEditor # 条码/二维码编辑器
│ └── ScheduleShiftsEditor # 班次 (班次代码替换)编辑器
```
### 6.2 作业文件格式
作业文件使用XML格式(VBfiles结构),保存场景内容和打印设置:
```xml
<VBfiles>
<!-- 打印设置 -->
<PrintSettings timeTriggerPrintMode="0" triggerInterval="90" ... />
<!-- 文本图元 -->
<VBfile>
<pointer_x>55</pointer_x>
<pointer_y>0</pointer_y>
...
<itemAttrs sourceType="1" dir="0" letterSpace="1" fontFamilay="WenQuanYi7" source="FGJ" ... />
</VBfile>
<!-- 日期图元 -->
<VBfile>
<pointer_x>55</pointer_x>
<pointer_y>0</pointer_y>
...
<itemAttrs sourceType="3" datetimePattern="HH:mm:ss" ... />
</VBfile>
<!-- 计数器图元 -->
<VBfile>
<pointer_x>83</pointer_x>
<pointer_y>17</pointer_y>
...
<itemAttrs sourceType="6" counter_type="7" digital_num="8" ... />
</VBfile>
<!-- 条码/二维码图元 -->
<VBfile>
<pointer_x>0</pointer_x>
<pointer_y>0</pointer_y>
...
<itemAttrs sourceType="5" dir="0" barcodeContentPattern="dr66re{t}{c}" barcodeType="2" qrcodeFormat="0" ... />
</VBfile>
<!-- 图片图元 -->
<VBfile>
<pointer_x>0</pointer_x>
<pointer_y>0</pointer_y>
...
<itemAttrs sourceType="2" dir="0" source="/home/plg/doc/scene.png" ... />
</VBfile>
</VBfiles>
```
### 6.3 关键类说明
- **PicSceneLoader** - 场景文件的加载/保存/预览,负责XML序列化/反序列化
- **ViewModels** - 定义 `DateItemModel`、`CounterViewModel` 等视图模型,用于编辑器与图元之间的数据传递
- **ItemCommon** - 图元工具函数,如根据日期模型生成文本字符串
- **打印设置** - `PrintSettingModel` 与作业文件绑定,包含触发模式、字宽、同步器参数等
- **TestPrintWidget** - 场景编辑器,提供图元的创建、编辑、删除、预览功能
---
## 7. 数据流与通信机制
### 7.1 打印内容数据流
```
用户编辑场景 (PicScene)
├── 普通静态图元 (PicTextItem, PicImageItem, ...)
│ └─── onPreviewScene() 静态文本或图片渲染为 QImage
│ └── imageToPrintData() 转换为点阵数据
│ └── SendPrintDataToFpga() 在打印开始前一次性发送所有静态打印内容
│ └── FPGA 接收并驱动喷头喷印
│
├─── PicCounterItem 计数器图元
│ └── onPreviewScene() 构建变量控制结构体(位置、大小、类型等)
│ └── DevOp::writeFpgaVariCtrl() 发送至FPGA,由FPGA直接硬件控制
│
└─── 软解动态图元 (PicDateItem PicScheduleShiftItem PicCodeItem)
└── onPreviewScene() 与静态图元一样,进入onPreviewScene()
└── variableItemsUpdate() 动态检查图元是否发生变化,更新数据
└── SendPrintDataToFpga() 发送更新后的点阵数据至FPGA
```
**打印内容相关的几个重要的函数:**
[SendPrintDataToFpga()](../mainwidget.cpp#L935) 负责将打印数据、打印设置和变量控制通过串口发送给FPGA,FPGA接收后驱动喷头进行喷印。静态图元在打印开始前一次性发送,而动态图元则在每次变化时更新打印数据。更新打印数据时,SendPrintDataToFpga不会发送打印设置和变量控制数据,只会按列为单位更新打印缓冲区的点阵数据。
[imageToPrintData()](../mainwidget.cpp#L675) 将 QImage 转换为点阵数据,该函数可将图像填充至打印缓冲区的指定位置,随后由 SendPrintDataToFpga() 发送至FPGA。动态软解图元(如日期、计数器、二维码)在每次变化时调用该函数刷新打印缓冲区。
[onPreviewScene()](../mainwidget.cpp#L1888) 是场景预览的核心函数,负责将场景中的所有图元渲染为 QImage,并调用 imageToPrintData() 全量写入打印缓冲区。
[variableItemsUpdate()](../mainwidget.cpp#L1024) 动态检查图元是否发生变化,配合 imageToPrintData()、SendPrintDataToFpga() 实现更新打印数据。
### 7.2 从文件到打印的数据流向
本节中 *发送打印设置与打印内容到FPGA* 的术语基本可以代指调用[MainWidget::SendPrintDataToFpga](../mainwidget.cpp#L933)函数。
区别于标准VX5,此韩国定制版中,明确了发送打印内容与打印设置到FPGA的时机与作用范围,所有发送打印内容与打印设置的动作只在[MainWidget::on_m_StartBtn_clicked()](../mainwidget.cpp#L756)中进行,除此之外其它时机发送打印内容与设置的行为继承自标准VX5,实际在韩国定制版中属于冗余设计。
QtUI 按工作文件为单位对喷码内容进行管理,工作文件使用 XML 格式保存场景内容和打印设置。用户在编辑界面(TestPrintWidget)中创建或修改工作文件后,点击“保存”按钮将场景数据序列化为 XML 文件。随后,用户在打印主界面(MainWidget)中选择工作文件并点击“打印”。
重要的工作流程位于[InkjetPrinter::loadWorkFileAndPreparePrint](../InkJetPrinter.cpp#L12684)函数中,流程如下:
```
用户点击 [MainWidget::m_AddBtn](../MainWidget.cpp#L143) (调入文件喷印) 发送 sendButtonClickedSignal(2) 信号
└── InkJetPrinter::getMainWidgetButtonClickedSlot() 接收信号打开 DialogFileOperation 对话框
└── InkjetPrinter::loadWorkFileAndPreparePrint() 通过对话框输入的文件名打开文件
└── PicSceneLoader::loadSceneFromFile() 解析 XML 文件,恢复场景内容和打印设置
└── MainWidget::generatePrintContent() 将场景渲染为打印数据并写入缓冲区
└── 等待用户按下 开始打印
└── MainWidget::SendPrintDataToFpga() 全量发送打印数据与设置到FPGA,并开始打印
```
注意打开并解析工作文件的过程中不会直接发送打印数据到FPGA,只有在用户点击“打印”按钮后,才会调用 SendPrintDataToFpga() 将打印数据发送至FPGA。
### 7.3 工作文件编辑
韩国QtUI中,*工作文件编辑* 被解耦为一个独立模块,它只负责对工作文件进行新建、编辑和调用[PicSceneLoader](../scene/PicSceneLoader.h)模块保存,其主要实现基本位于[TestPrintWidget](../testprintwidget.h),[TestPrintWidget](../testprintwidget.h)通过读取指定工作文件(或新建),在编辑完成后可以对文件进行保存。
```
用户点击 (新建文件) (编辑文件) 发送信号到InjkectPrinter
└── InkJetPrinter判断当前文件名,将文件名传给TestPrintWidget,并切换到TestPrintWidget视图
└── TestPrintWidget完成编辑后询问用户是否保存已编辑的工作文件
├── 用户选择保存,TestPrintWidget 使用 PicSceneLoader 写入xml工作文件
│ └─ 保存文件后发出信号通知 InjkectPrinter
│ └─ InkjectPrinter 切换到 MainWidget 并调用 loadWorkFileAndPreparePrint 载入刚刚保存的文件
│ └─ 之后的流程与 7.2 小节一致
│
└── 用户选择不保存,TestPrintWidget 直接发出信号通知 InjkectPrinter
└─ InkjectPrinter 切换到 MainWidget,然后什么也不做
```
### 7.4 设备状态轮询
```
timerHandler()
├── serialFPGA->readData() # 读取FPGA状态寄存器
├── serialSTM32->readData() # 读取STM32传感器数据
├── saveFPGAStatus() # 解析FPGA状态
│ ├── 墨线开关、高压状态、回收故障
│ ├── 墨水/溶剂液位警告
│ └── 相位检测结果
├── saveSTM32Status() # 解析STM32状态
│ ├── 齿轮泵转速
│ ├── 脉冲计数
│ └── 压力/粘度值
├── MainWidget::updateSysStatusToUI() # 更新界面状态灯
└── autoControlValvePump() # 自动控制执行
```
### 7.5 信号槽通信概览
```
Serial::receivedFromFPGA ──→ InkJetPrinter::saveFPGAStatus()
Serial::receivedFromSTM32 ──→ InkJetPrinter::saveSTM32Status()
MainWidget::sendButtonClickedSignal ──→ InkJetPrinter::getMainWidgetButtonClickedSlot()
TestPrintWidget::sendButtonClickedSignal ──→ InkJetPrinter::getTestPrintWidgetButtonClickedSlot()
RunTimeCtrl::sig_alertTimeout ──→ InkJetPrinter::slt_warningMaintenance()
RFIDManager::sig_showMsg ──→ InkJetPrinter::slt_showMsg()
```
---
## 8. RFID刷卡模块
### 8.1 模块概述
[RFIDManager](../rfid/rfidmanager.h)
**职责**: 管理IC卡(墨水卡、溶剂卡、保养卡)的读写与验证。
**功能**:
- 墨水/溶剂添加验证(刷卡 + 物理添加)
- 保养卡识别与提醒
- 卡片使用标记(防重复使用)
- 超级卡的识别与处理
**加密**: 使用SM3(哈希)+ SM4(对称加密)国密算法保护卡片数据。
### 8.2 刷卡流程
```
检测到墨水/溶剂不足
└── 弹出刷卡提示对话框
└── 用户刷卡
├── RFIDManager 读取卡片数据
├── 验证卡片类型和有效性
├── 标记卡片为已使用
└── 通知 InkJetPrinter 更新报警状态
```
---
## 9. 编译构建系统
### 9.1 编译配置
项目使用 qmake 构建系统,主配置文件为 [QtUI.pro](../QtUI.pro)。
**目标平台**:
- ARM Linux: `TARGET = QtUI`
- 交叉编译: 使用 `linux-aarch64-gnu-g++` mkspec
- x86桌面: 使用 `linux-g++` mkspec,用于开发调试
### 9.2 模块依赖
```makefile
QT += core gui network serialport virtualkeyboard sql xml
```
### 9.3 编译命令
下面给出 InkjetUbuntu-T1 环境下调试、发布的编译方式
```bash
# ARM交叉编译
cd /path_to_your_arm_build_dir/ && /home/inkjet/QtSDK/bin/qmake /path_to_your_sources_dir/QtUI.pro -spec linux-aarch64-gnu-g++ CONFIG+=release
make -j
# x86桌面编译(调试)
cd /path_to_your_x86_build_dir/ && /home/inkjet/QtSDKPC/bin/qmake /path_to_your_sources_dir/QtUI.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug
make -j
```
### 9.4 发行编译
VX5 Release编译发行.md 给出了如何发布带崩溃转储的程序的流程
---
## 10. 关键配置与宏定义
### 10.1 全局宏 ([myinclude.h](../myinclude.h))
| 宏 | 说明 |
|-----|------|
| `__RFID_CARD` | 启用刷卡功能 |
| `__RFID_OLD` | 旧加密算法 |
| `__RFID_IND` | 印度二次加密 |
| `MULTILANGUAGE` | 多语言输入法 |
| `EnableArabic` | 阿拉伯语支持 |
| `EnableBangla` | 孟加拉语支持 |
| `TEST_MODE` | 测试模式 |
| `SIMULATE_PRINTING_MODE` | 模拟打印模式 |
### 10.2 路径定义 ([SysPara.h](../SysPara.h))
| 路径宏 | 值 | 说明 |
|--------|-----|------|
| `PARA_ROOT_DIR` | `/home/plg/conf/` | 系统参数目录 |
| `DOC_ROOT_DIR` | `/home/plg/doc/` | 作业文件目录 |
| `SYS_ROOT_DIR` | `/home/plg/` | 系统根目录 |
| `UDISK_DOC_ROOT_DIR` | `/udisk/doc/` | U盘文档目录 |
### 10.3 版本号 ([VerBVersion.h](../VerBVersion.h))
```cpp
#define UP_PRINTER_MAJOR_VER 6
#define UP_PRINTER_MINOR_VER 7
#define UP_PRINTER_RIVISION_VER 5
#define SUB_VERSION "_KOR"
```
版本号分为年、月、本月第几次编译,SUB_VERSION表示是否是标准版,"_Std" 表示标准版,"_KOR" 表示韩国定制版、"_RFID" 表示是标准版基础上增加了刷卡功能,如果客户定制版本包含了刷卡功能,则显示客户后缀。
---
## 11. 上手指南
### 11.1 开发环境搭建
1. **安装Qt**: 推荐 Qt 5.12+ 用于桌面开发调试
2. **获取代码**: 找到你的领导,通过SVN获取源码
3. **编译运行**:
1. 直接使用 InkjetUbuntu-T1 虚拟机中的 QtCreator 打开此项目,然后编译调试。
2. 使用 VSCode ssh 连接 InkjetUbuntu-T2(从T1升级至Ubuntu20.04,以支持VSCode SSH连接) 虚拟机,然后直接在windows上远程开发,此方式需要自行配置编译环境,编译为ARM版本的命令为:
```bash
$ /home/inkjet/QtSDK/bin/qmake ./QtUI.pro -spec linux-aarch64-gnu-g++ CONFIG+=release
$ make -j8
```
4. **注意事项**: x86桌面版仅用于UI调试,硬件相关功能(串口、FPGA通信)不可用。
### 11.2 代码阅读顺序建议
1. **入门**: [main.cpp](../main.cpp) → [myinclude.h](../myinclude.h) → [InkJetPrinter.h](../InkJetPrinter.h)
2. **核心数据**: [SysPara.h](../SysPara.h) → [DevOp.h](../DevOp.h)
3. **UI页面**: [MainWidget](../mainwidget.h) → [TestPrintWidget](../testprintwidget.h)
4. **场景系统**: [scene/picscene.h](../scene/picscene.h) → [scene/PicSceneLoader.h](../scene/PicSceneLoader.h) → [scene/ItemCommon.h](../scene/ItemCommon.h)
5. **通信层**: [Serial/serial.h](../Serial/serial.h)
6. **RFID**: [rfid/rfidmanager.h](../rfid/rfidmanager.h)
### 11.3 常见开发任务
| 任务 | 涉及文件 | 说明 |
|------|---------|------|
| 添加新图元类型 | `scene/` 目录 | 继承 PicTextItem,实现渲染和序列化 |
| 修改打印设置 | `Printsetting.h/cpp` | 修改 PrintSettingModel 结构体 |
| 添加新语言 | `*.ts` 文件 | 使用 Qt Linguist 编辑翻译 |
| 修改FPGA通信 | `DevOp.h/cpp` + `Serial/` | 注意地址空间分配和CRC校验 |
| 修改UI样式 | `.ui` 文件 | 使用 Qt Designer 编辑 |
| 添加新功能页面 | 仿照现有页面模式 | 创建 .h/.cpp/.ui 三件套 |
| 添加网络通信 ||
### 11.4 关键设计模式
- **单例模式**: `RFIDManager`, `RunTimeCtrl`, `LogInfoCtrl` 使用单例
- **观察者模式**: 大量使用Qt信号槽进行模块间通信
- **策略模式**: 打印触发模式(时延/电眼/同步器)通过枚举切换
- **MVC变体**: 场景系统使用 ViewModel (`ViewModels.h`) 解耦编辑器与图元
### 11.5 调试技巧
1. **日志**: Debug模式下使用 `qInfo()/qWarning()/qCritical()` 输出,日志文件位于 `/home/plg/conf/`,发行版使用`LogInfo::setRunStatus()`
2. **崩溃分析**: `dump.h/cpp` 安装了信号处理器,崩溃时会生成core dump
3. **泵阀手动控制**: 可通过 `SystemManage` 界面手动控制阀门和泵
4. **模拟模式**: 设置 `SIMULATE_PRINTING_MODE 1` 可在无硬件环境调试打印逻辑
### 11.6 注意事项
- **不要直接操作硬件寄存器**: 必须通过 `DevOp` 类进行设备操作
- **参数持久化**: 修改系统参数后需调用 `SysPara` 的保存方法
- **线程安全**: 串口通信在独立线程中,注意跨线程信号槽的连接方式
- **版本兼容**: 注意 `#ifdef` 条件编译宏,不同客户可能有不同的功能组合
- **UI文件**: 项目使用 `.ui` 文件定义界面,编译时通过 `uic` 生成 `ui_*.h` 文件
- **编码**: 所有源文件使用 UTF-8 编码,字符串使用 `QString::fromUtf8()` 或 `tr()`
---
> **文档维护**: 本文档应随项目迭代持续更新。如有疑问,请联系项目负责人。
**文档更新记录**
- 2026-07-29:继续完善了此文档 - 卜永仕
- 2026-07-23:创建此文档 — 卜永仕