开源 串口调试助手 / 网络调试工具,把 UART 串口终端与 TCP/UDP 调试合在同一界面。面向嵌入式开发、设备联调、Modbus / 自定义协议测试与通信日志分析;正式发行包支持 Windows、macOS 与 Linux x86_64。
Serial / UART terminal and TCP/UDP network debugger in one desktop app — HEX, logging, Modbus, scripting, and automated tests.
下载最新版 · 中文使用说明 · English Usage
CommTool(通信调试工具)由原 SerialTool 与 NetworkTool 合并:左上角切换 Serial / UDP / UDP Multicast / TCP Server / TCP Client / Virtual,收发区、关键字高亮、批量发送、录制回放与自动化能力一套通用,不必再为串口和网络各装一个工具。产品与发行包名:CommTool;Git 仓库路径仍为 heropml/SerialTool(不改仓名,避免更新链接断裂)。
适合: MCU / USB 转串口调试 · TCP/UDP 服务联调 · Modbus 主从与扫描 · 周期/批量指令 · 会话日志与(有限范围)PCAP 导出 · 无硬件时用 Virtual 回环复现问题
- 串口 + 网络 + 虚拟一体:串口参数、TCP/UDP、组播、多客户端 TCP Server,以及无硬件 Virtual 回环,同一套操作习惯。
- 数据看得清、留得住:文本 / HEX / HEX 转储 / 数值视图,可选终端模式;时间分包、关键字与协议高亮、搜索与书签;实时日志与
.ctrec录制回放。 - 从手工到自动化:多条命令、定时发送、命令 DSL、自动应答、触发告警、脚本控制台、宏录制、序列测试与 JUnit 报告。
- 面向设备协议:多种校验(含 CRC / Modbus 等)、Modbus 主从机 / 扫描 / TCP↔RTU 网关、寄存器与位域、结构化记录、波形图与 I/O Graph。
- 开箱即用:Windows 安装包 / 便携版、macOS
.dmg、Linux x86_64.run均可直接运行;简体中文、English、繁體中文;支持在线更新。
| 能力 | 说明 |
|---|---|
| 连接类型 | Serial、UDP、UDP 组播、TCP Server / Client、Virtual(无硬件回环) |
| 显示与检索 | 文本 / HEX / HEX 转储 / 数值;终端模式;关键字与协议高亮;搜索、书签 |
| 协议与校验 | Modbus 主从 / 扫描 / TCP↔RTU 网关;CRC 等校验选项;寄存器 / 位域 |
| 日志与取证 | 实时日志、.ctrec 录制回放;TCP Client / TCP Server(含多客户端)、UDP(指定远程)、UDP 组播 可导出 .pcap / .pcapng(合成报文,非网卡抓包;串口等仍用 .ctrec) |
| 自动化 | 定时 / 多条发送、自动应答、触发器、脚本控制台、宏录制、序列测试与 JUnit |
| 分析与工程 | 波形图 / I/O Graph / 仪表盘、多会话标签、.ctproj 工程与示例、桥接与文件传输、三语与在线更新 |
- 打开 Releases,下载 Windows 安装包 / 便携版、macOS
.dmg或 Linux.run。 - Windows:启动
CommTool.exe(便携版请保留整个dist\CommTool\目录)。 - 在「类型」选择 Serial、目标网络协议或 Virtual,填参数后连接。
- 在右侧收发区查看数据;HEX、校验、定时发送、日志等在左侧对应开关中开启。
没有硬件?选 Virtual(虚拟连接) 并开回环,即可先验证发送、解析、脚本和自动化规则;回放
.ctrec也需先连 Virtual。
- 1. 功能总览
- 1.1 连接设置(串口 / 网络)
- 1.2 数据区
- 1.3 发送区
- 1.4 界面
- 1.5 关闭程序 + 系统托盘
- 1.6 图标固化
- 1.7 持久化
- 1.8 在线更新
- 2. 三种使用方式
- 3. 文件结构
- 4. 从源码运行
- 5. 重新打包
- 5.1 文件夹版
- 5.2 单文件版 (onefile)
- 5.3 安装版 (Inno Setup)
- 5.4 Linux 版
- 5.5 改版本号
- 6. 换图标
- 7. 依赖
- 8. 已知问题与注意事项
- 9. 技术说明
- 9.1 iOS 滑动开关
- 9.2 连接层(串口 + 网络)
- 9.3 编码兼容
- 9.4 时间戳分包 / 换行分包 逻辑
- 9.5 跨包"待新块"标志
- 9.6 自定义标题栏 + Aero Snap
- 9.7 QSettings 持久化
- 9.8 主题系统
- 9.9 字符编码
- 9.10 CRC 算法实现
- 9.11 HEX 输入宽容化
- 10. 版本历史亮点
- 类型下拉:Serial(串口)/ UDP / UDP Multicast(组播)/ TCP Server / TCP Client / Virtual(虚拟)(新装默认 Serial)
- 串口(Serial):端口(下拉本机串口 + ⟳ 刷新)+ 波特率(可编辑,1200~2000000)+ 数据位(5/6/7/8)+ 校验位(None/Even/Odd/Mark/Space)+ 停止位(1/1.5/2)→「打开串口」;后台线程定时扫描串口热插拔
- 网络类型字段随协议动态显隐:
- UDP:本地IP(下拉本机网卡,0.0.0.0=所有)+ 本地端口 +「指定远程」开关(关=回复最近对端,开=固定发往远程IP/端口);关闭时收到数据自动把灰显的远程框刷成最近对端地址(显示当前对端,打开开关即预填)
- UDP Multicast:本地IP(出/入网卡)+ 组播地址(224.0.0.0~239.255.255.255)+ 本地端口
- TCP Server:本地IP + 本地端口 →「开始监听」;连入后「目标」下拉可选某客户端或「全部」广播
- TCP Client:远程IP + 远程端口 →「连接」
- Virtual(虚拟):不接硬件即可开连接;可开「回环」;用于无设备验证规则/脚本,以及
.ctrec回放注入 - 动作按钮随协议/状态:打开/关闭、开始监听/停止监听、连接/断开;连接后整卡片锁定变灰
- 基于 Qt 自带 QtNetwork(QTcpServer/QTcpSocket/QUdpSocket),事件驱动、无轮询线程;串口走 pyserial,Virtual 为进程内注入
收发数据同框显示,箭头区分方向、颜色区分类型:
| 标记 | 含义 | 颜色 |
|---|---|---|
← |
RX 接收 | 灰黑(#1C1C1E) |
→ |
TX 发送 | 主题强调蓝(#007AFF) |
显示选项(侧边栏 → 数据区)
- 显示方式 — 文本 / HEX / HEX 转储 / 数值(互斥下拉);转储可选行宽,数值可选类型与字节序;收发一致,与「HEX 发送」无关
- 字符编码 — Auto / UTF-8 / GBK / GB2312 / GB18030 / Big5 / ASCII / Latin-1 共 8 项;Auto 走 UTF-8 优先 + GBK 容错回退,其他用
codecs.IncrementalDecoder处理跨包多字节。影响 RX 解码 / TX 文本编码 / 文件加载 - 自动换行 — 控制
QTextEdit的 WordWrap 模式 - 显示时间戳 — 每个新块前缀
[2026/06/03 09:48:54 023](年月日补零,毫秒 3 位),独立开关 - 时间分包 + 超时 ms — 两次 RX 到达间隔 > 超时则切包另起一行,独立开关("显示时间戳"和"时间分包"各管各的)
- 换行分包 + 换行符模式(Auto / CRLF / LF / CR) — 按文本换行符切包
Auto:\r\n、\r、\n全识别(Windows + Linux + Classic Mac 都兼容)- 严格模式:只认指定终止符,其他换行符按数据字节看待
- 实时记录 — Xshell 风格连续日志写到
.log文件,显示什么写什么(带时间戳、箭头、HEX/ASCII),会话开头/结尾自动加分隔行 - 最大行数 — 显示行上限,超出自动丢弃最老的行,避免长时间运行卡顿;不影响日志文件
- 字号
A−A+可调(7–28 pt 范围) - 保存 / 清空按钮
- 滚动锁定 / 自动跟随(v1.0.1)— 往上翻时视图定住、数据照常接收;右下角浮动「↓ 最新」按钮回到底部并恢复自动跟随
- 单击行高亮(v1.0.1)— 鼠标单击数据区某一行整行高亮,再点取消
- 关键字高亮(v1.0.1)— 标题栏「关键字高亮」按钮打开配置弹窗:多条关键字,每条独立颜色、可选「背景 / 文字」着色、可限定「收 / 发 / 收发」范围;区分大小写子串匹配、跳过时间戳、规则持久化
- 只显高亮行(v1.0.1,v1.0.2 移到数据区标题栏)— 标题栏「只显高亮行」可切换按钮(开启时高亮),只保留命中关键字的行(其余折叠隐藏,数据不丢)
- 关键字高亮分组(v1.0.2)— 弹窗左侧分组列表(新建/双击改名/删除);标题栏分组下拉选「哪个分组生效」(含「(关闭)」停用全部);编辑分组与生效分组相互独立
- 实时记录按大小分包(v1.0.2)— 实时记录开关旁下拉:不分包 / 1M~100M / 自定义(如 3M);写满自动切到
_001/_002新文件;当前日志路径显示在底部状态栏 - 中文右键菜单(v1.0.2)— 数据区右键 复制 / 全选 / 清空 / 保存,跟随程序语言(非系统语言的 Qt 默认菜单)
发送选项(侧边栏 → 发送区)
- HEX 发送 — 把输入框内容当 HEX 字符解析(
AA BB、AABB、AA-BB、AA:BB、AA,BB、带0x前缀等都接受) - 追加换行 + 换行符模式(CRLF / LF / CR) — 自动在尾部追加对应字节,下拉框默认 CRLF
- 定时发送 + 周期 ms — 最小 10ms,发送失败时(未连接 / 数据格式错误 / 无目标等)自动停止
- 追加校验(9 种算法 +「无」)
| 算法 | 长度 | 说明 |
|---|---|---|
| 无 / None | 0 | 不追加 |
| 和校验 / ADD8 | 1 | sum & 0xFF |
| 累加和取反 / ~ADD8 | 1 | (~sum) & 0xFF |
| 异或 / XOR8 | 1 | 全字节异或 |
| CRC8 | 1 | 多项式 0x07(标准 CRC-8/CCITT) |
| ModbusCRC16 | 2 | poly 0xA001, init 0xFFFF, 小端(Modbus RTU 标准) |
| CCITT-CRC16 | 2 | CRC-16/CCITT-FALSE: poly 0x1021, init 0xFFFF, 大端 |
| CRC32 | 4 | Ethernet / ZIP 标准(zlib.crc32),大端 |
| ADD16 | 2 | 16 位累加和,大端 |
| MOBUS | 1 | CRC8 with poly 0x31 — 对应国内嵌入式社区常见 MG_Crc8Check / crc8_ccitt 实现 |
操作
- 读取文件 → 把文件内容塞进发送框(HEX 模式自动转 hex 字符串)
- 清空发送框
- 发送按钮 + 状态栏 收发速率 / 包统计(v1.1.0)— 底部状态栏 RX/TX 显示「字节 · 包数 · 实时速率(B/s)」,悬停看完整明细(含峰值速率、错误数),右键「重置统计」清零
- 多条发送(v1.0.1)— 「多条发送」按钮打开弹窗:每行一条数据 + 复选框,每行可独立设 HEX / 换行 / 校验;条目持久化
- 多条发送分组 + 主界面快捷栏(v1.0.2)— 弹窗左侧分组列表 + 每行加「名称 / 延时(ms)」;发送区上方快捷栏
[多条发送][▶循环][分组下拉] + 命令平铺按钮,点按钮直接发、不用开弹窗;循环发送按每行各自延时依次轮发
-
窗口边框:Windows / Linux 为无边框自绘标题栏(图标 + 标题 + 语言 / 主题下拉 + 最小化/最大化/关闭);macOS 使用系统原生标题栏(红黄绿)
- 语言 + 主题下拉都在标题栏左侧(紧挨标题;macOS 布局随系统栏适配)
- Windows:拖标题栏移动、双击最大化;边缘缩放走原生
WM_NCHITTEST(Aero Snap 可用)
-
圆角卡片与滑动开关
- 圆角卡片 + 柔和投影(
QGraphicsDropShadowEffect) - 自绘滑动开关(历史类名
IOSSwitch),带缓动动画 - 主按钮 / 幽灵按钮 / 图标按钮三套样式
- Default 主题强调色
#007AFF、#34C759绿、#FF3B30红(其他主题各自有 accent / danger)
- 圆角卡片 + 柔和投影(
-
左侧 sidebar + 右侧数据区
- 左:连接设置 / 数据区设置 / 发送区设置 三张卡片,
QGridLayout让所有右侧控件右对齐 - 右:数据日志区 + 发送输入框(垂直可拖)
- 左右用
QSplitter分隔,宽度可调(侧边栏 240–360 px)
- 左:连接设置 / 数据区设置 / 发送区设置 三张卡片,
-
状态栏
- 左下:状态点(红 = 未连接 / 绿 = 已连接·监听·已绑定)+ 连接状态文本(串口
● COM3 @ 115200;网络● TCP 监听 / ● 已连接 / ● UDP / ● 组播 地址:端口;Virtual● Virtual)+ RX/TX 收发统计(字节 · 包数 · 实时速率,详见 v1.1.0) - 右下:版本号
v1.5.7(从version.py同步),有新版时变成「● 可更新 vX」可点徽标;左侧显示当前实时记录文件路径(📝)
- 左下:状态点(红 = 未连接 / 绿 = 已连接·监听·已绑定)+ 连接状态文本(串口
-
多语言切换:标题栏左上下拉(简体中文 / English / 繁體中文),无需重启,所有 UI 文字(标签、按钮、占位提示、错误消息、文件对话框)瞬间切换
-
主题切换:标题栏左上紧挨语言的第二个下拉,9 个终端风配色方案:
主题 mode 风格 Default light 浅色默认(白卡片 + 浅灰窗口) Dark dark VSCode 通用暗 One Half Light / Dark light/dark Atom 编辑器风 Solarized Light / Dark light/dark 经典 Solarized Tango Dark dark Linux Tango 灰 Campbell dark Windows Terminal 默认黑 Ubuntu dark Ubuntu 紫 主题驱动整体配色:窗口背景 / 卡片 / 按钮 / 输入框 / 数据区 / 状态栏 / 关闭对话框全部跟着切。算法上每个主题只定义 4 个核心色(
bg/fg/tx/ts)+mode,chrome_for()用_mix()派生出 19 个 chrome 色(card_bg / input_bg / ghost / scrollbar / 等)。
点窗口右上 × 弹出三选一对话框:
| 选项 | 行为 |
|---|---|
| 最小化到托盘(默认) | hide() 隐藏窗口,托盘弹气泡通知 |
| 退出程序 | 真退出 — 存配置 + 断开连接 + 关日志 |
| 取消 | 关闭事件被吃掉,窗口保留 |
系统托盘图标(任务栏右下角通知区):
- 单击 / 双击 → 恢复窗口
- 右键菜单 → "显示窗口" / "退出"
- 切换中英文时托盘菜单文字同步
- 系统不支持托盘时,
×直接退出(不弹对话框)
128×128 PNG 图标用 base64 编码写死在独立的 icon_data.py 文件里(ICON_B64 常量),main.py 通过 from icon_data import ICON_B64 as _APP_ICON_B64 导入,运行时由 get_app_icon() 解码加载。带来的好处:
- 别人没法通过替换
icon.ico来改窗口/任务栏/托盘里显示的图标 - 打包出的
dist\CommTool\_internal\里完全没有icon.ico文件 - 资源管理器里 exe 文件的图标仍然来自 PyInstaller 的
--icon嵌入资源(这是 Windows 资源段,跟运行时图标分开)
启动时自动从 settings.ini 恢复,关闭时自动保存:
- 窗口位置 + 大小(含最大化状态)
- 两个 splitter 的精确位置
- 当前语言(中文 / 英文)
- 所有开关 / 输入框 / 下拉选项
- 发送框内容
- 字号、最大行数
位置:CommTool.exe 同级目录的 settings.ini,整个 dist\CommTool\ 文件夹可以连配置一起复制到其他机器。
关于 → 检查更新(v1.0.4):系统托盘右键菜单新增「关于」入口,打开对话框显示图标 / 名称 / 版本 / 简介 + 「检查更新」按钮。
- 点「检查更新」自动从更新源读取版本清单(
latest.json),与当前版本比对- 有新版 → 显示版本号 + 更新说明 + 「下载并更新」→ 下载(带进度)→ 下载完弹出正常安装向导,手动点「下一步 / 安装」完成升级(非静默)
- 已是最新 → 提示当前已是最新版本
- 更新源内网优先、回退公网(GitHub 上 CommTool 分支的
latest.json),每个源 8 秒超时(外网不卡) - 下载后校验文件头魔数(
MZ)防错误页误执行;关闭对话框 / ESC 自动中止在途下载并删半成品;启动时清理%TEMP%残留安装包;版本号解析容错 - 网络类型基于 Qt 自带 QtNetwork(CommTool 网络侧本就用 QtNetwork),无新依赖;更新源地址在
src/updater.py的UPDATE_MANIFEST_URLS配置,版本清单格式见根目录latest.json
dist\CommTool\CommTool.exe
整个 dist\CommTool\ 文件夹(约 98 MB)可以复制到任意 Windows 10/11 64 位电脑直接运行,目标机器无需安装 Python、PyQt5。
双击 scripts\run.vbs — 完全无窗口启动(优先 pyw src\main.py,回退 pythonw src\main.py),没有 cmd 闪屏。
双击 scripts\run_debug.bat — 保留 cmd 窗口,能看到 Python 异常输出,方便排查问题。
代码已按模块拆分,并把源码 / 文档 / 脚本 / 资源分类到子目录。所有脚本内部用
cd %~dp0..(或dirname/..)切回项目根再执行,双击即用,无需手动 cd。
CommTool/
├── README.md 开发者文档(本文件,留在根目录)
├── requirements.txt 运行时依赖
├── requirements-dev.txt 开发/打包/单测依赖(含 -r requirements.txt)
├── latest.json 在线更新版本清单(version / url / notes)
│
├── src/ Python 源码(按模块拆分)
│ ├── main.py 入口:HiDPI + QApplication + 启动 CommTool
│ ├── main_window.py 主窗口 CommTool 主体类(最大模块)
│ ├── dialogs.py 多条发送 / 关键字高亮 / 关闭确认 弹窗
│ ├── widgets.py 自定义控件(IOSSwitch / TitleBar / Card)
│ ├── serial_io.py 串口连接层(SerialConn + SerialReader 读线程 + 端口扫描)
│ ├── net_io.py 网络连接层(TCP Server/Client、UDP、UDP 组播)
│ ├── theme.py 主题配色表 + 角色着色(ROLE_*)
│ ├── i18n.py 三语翻译表(简 / 英 / 繁)
│ ├── app_icon.py 运行时图标加载(resource_path / get_app_icon)
│ ├── icon_data.py 128×128 PNG base64(运行时图标,~545 行)
│ ├── updater.py 在线更新(QtNetwork 检查/下载 + 跑安装向导)
│ └── version.py 版本号单点真源 (__version__ = "1.5.7")
│
├── docs/ 文档
│ ├── USAGE.md 用户文档(英文,安装包附带)
│ ├── 使用说明.md 用户文档(简体)
│ ├── 使用說明.md 用户文档(繁体)
│ └── RELEASE_NOTES.md 版本发布说明
│
├── scripts/ 构建 / 启动脚本(内部 cd 回根目录)
│ ├── run.vbs 静默启动(推荐日常用)
│ ├── run.bat 快速启动(cmd 一闪而过)
│ ├── run_debug.bat 调试启动(保留 cmd 看错误)
│ ├── build.bat 打包文件夹版 exe(py -3 -m PyInstaller)
│ ├── build_onefile.bat 打包单文件版 exe(文件名带版本号)
│ ├── build.sh Linux 打包脚本(venv + 国内镜像 + 捆绑 xcb + .run 安装器)
│ ├── package_linux.sh 把 dist 打成 .run / .tar.gz
│ ├── release_linux.sh 上传 Linux .run 到已有 GitHub Release 并写 url_linux
│ ├── build_installer.bat 编译 Inno Setup 安装包(自动从 version.py 取版本号)
│ ├── release.ps1 一键发版(改版本→改 latest.json→打包→push→建 Release)
│ └── CommTool.iss Inno Setup 脚本(多语言 EN/简/繁,路径可选)
│
├── assets/ 图标资源
│ ├── icon.ico 多分辨率 ICO(16/32/48/64/128/256 px,透明背景)
│ ├── icon_preview.png 256×256 PNG 预览(icon_convert.py 输出的副产品)
│ └── icon_convert.py 一次性脚本:JPG/PNG → 多尺寸透明 ICO
│
├── build/ build_onefile/ PyInstaller 中间产物(gitignore)
├── dist/ PyInstaller 文件夹版输出
│ └── CommTool/ 【独立可执行版本 — 把这个文件夹拷走就能用】
│ ├── CommTool.exe 图标已嵌入 exe 资源段
│ └── _internal/ Python + Qt DLL(不含 icon.ico — 图标在源码里 base64)
├── dist_onefile/ PyInstaller --onefile 输出 CommTool_onefile_v*.exe
└── installer/ Inno Setup 输出 CommTool_Setup_v*.exe
运行时用户配置
settings.ini:打包版落在 exe 同级(装不进 Program Files 时回退%APPDATA%\CommTool\);开发模式落在源码同级(已 gitignore)。
# 1. 装依赖(清华镜像,国内快)
# 仅运行:requirements.txt;开发/单测/打包:requirements-dev.txt
pip install -r requirements-dev.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 2. 启动
py -3 src\main.py要求 Python ≥ 3.9(实际测试在 3.13)。
三种产物的构建脚本互相独立,按需调用:
scripts\build.bat
输出 dist\CommTool\ (约 98 MB 整个文件夹,含 CommTool.exe + _internal/)。整个文件夹可拷贝携带使用。
构建命令(简化版,从项目根执行):
py -3 -m PyInstaller --noconfirm --clean --windowed ^
--name CommTool --icon assets\icon.ico ^
src\main.py用
py -3 -m PyInstaller而非裸pyinstaller:后者可能命中 PATH 里的旧版本静默失败。
⚠️ 没有--add-data icon.ico:图标已经 base64 编码在src\icon_data.py里(被app_icon.pyimport),运行时不读取外部文件。--icon assets\icon.ico是 PyInstaller 把图标嵌入 exe 文件本身的 Windows 资源段(让资源管理器里 exe 显示图标),跟运行时窗口图标是两回事。
build.bat 加了 20+ 个 --exclude-module 排除不用的 Qt 模块(WebEngine、Multimedia、Bluetooth、Quick/QML、Sql 等),把打包体积从默认 ~150 MB 砍到 ~98 MB。
scripts\build_onefile.bat
自动从 src\version.py 读版本号,输出 dist_onefile\CommTool_onefile_v<版本>.exe(38 MB 单文件,文件名带版本号,与安装包一致)。首次启动稍慢 12 秒(自解压到 %TEMP%),之后跟文件夹版无差。
等价命令(v%VER% 由脚本从 version.py 注入到 --name):
py -3 -m PyInstaller --noconfirm --clean --windowed --onefile ^
--name CommTool_onefile_v1.4.2 --icon assets\icon.ico ^
--distpath dist_onefile --workpath build_onefile ^
src\main.py前置:winget install JRSoftware.InnoSetup(一次性)。然后:
scripts\build_installer.bat
自动从 src\version.py 读 __version__,传给 ISCC 编译 scripts\CommTool.iss,输出 installer\CommTool_Setup_v<版本>.exe (~28 MB)。
安装包特性:
- 多语言(英 / 简中 / 繁中,第一步选)
- 路径可选(默认
%LocalAppData%\Programs\CommTool\,可改任意盘) - per-user 安装无需管理员;选"为所有用户"自动提权装到 Program Files
- 自动创建开始菜单 + 桌面快捷方式(可选)+ 控制面板卸载条目
官方安装包(x86_64,建议在 Ubuntu 18.04 或同级 glibc 上构建,以便 20.04/22.04/麒麟也能跑):
chmod +x CommTool_Setup_v1.5.7_linux_x86_64.run
./CommTool_Setup_v1.5.7_linux_x86_64.run默认装到 ~/.local/opt/CommTool(无需 sudo),并写入应用菜单与桌面图标。卸载:~/.local/opt/CommTool/uninstall.sh。用户向安装步骤见 docs/使用说明.md §9 / USAGE / docs/使用說明.md §6。
从源码打包:
bash scripts/build.shbuild.sh 用 venv 隔离 + 清华镜像 + PyInstaller,并把 xcb/X11 库打进包内;最后输出 installer/CommTool_Setup_v*_linux_x86_64.run。发布到已有 tag:bash scripts/release_linux.sh。PyInstaller 不支持交叉编译,必须在 Linux 上跑。
只改 src\version.py 一处:
__version__ = "1.3.8"然后重新跑上面任意构建脚本。状态栏右下版本号 + 安装包文件名 CommTool_Setup_vX.X.X.exe 同时同步。CommTool.iss 通过 #ifndef MyAppVersion #define ... 接受 ISCC 命令行 /DMyAppVersion=... 覆盖。
替换图标分两个层面:
exe 文件本身的图标(资源管理器里看到的):
- 把新原图存为
assets\icon_src.png或assets\icon_src.jpg(任意分辨率,自动居中裁剪成方形) - 运行
python assets\icon_convert.py生成assets\icon.ico(自动抠白底背景 + 边缘羽化) - 双击
scripts\build.bat重新打包
程序运行时显示的图标(窗口标题栏 / 任务栏 / 托盘):
需要重新生成 base64 替换 src\icon_data.py 里的 ICON_B64:
python -c "from PIL import Image; img = Image.open('assets/icon_preview.png').convert('RGBA'); img.thumbnail((128, 128), Image.LANCZOS); img.save('_icon_embed.png', 'PNG', optimize=True)"
python -c "import base64, textwrap; b64 = '\n'.join(textwrap.wrap(base64.b64encode(open('_icon_embed.png','rb').read()).decode(), 76)); open('src/icon_data.py','w',encoding='utf-8').write(f'# -*- coding: utf-8 -*-\nICON_B64 = \"\"\"\\\n{b64}\n\"\"\"\n')"第二条命令直接把新的 icon_data.py 写出来(约 545 行 base64)。
抠图算法:从四个角洪水填充识别同色背景区域,把这些像素的 alpha 设为 0,再做 1px 高斯模糊让边缘平滑。角色内部的白色(牙齿、眼睛高光等)因为不和四角连通,不会被误抠。
| 包 | 版本 | 用途 |
|---|---|---|
| PyQt5 | ≥ 5.15 | GUI 框架 + 网络(QtNetwork,随 PyQt5 自带,无需单独装) |
| pyserial | ≥ 3.5 | 串口收发(Serial 连接类型) |
| pyinstaller | ≥ 6.0 | 打包 exe(仅开发时需要) |
| Pillow | ≥ 10.0 | 图标转换(仅 icon_convert.py 用) |
- HEX 发送内容必须是偶数个 hex 字符(空格 / 横线 / 冒号等任意分隔符可省)
- 定时发送最小周期 10 ms,发送失败时(未连接 / 数据格式错误 / 无目标等)自动停止
- UDP 不指定远程且未收到过任何对端时,发送会提示「无可发送目标」;TCP Server 无客户端连入时同理
- 组播收发需防火墙放行、收发端在同一组播地址/端口且同网段
- macOS / Linux 字体优先级会按系统回退,UI 在 macOS PingFang SC、Linux Noto Sans CJK 下也能正常显示(主要测试环境是 Windows 11)
- 频繁切换语言时 IOSSwitch 不触发动画(按设计),其他控件文本会闪一下属正常
- 每个标签独立连接、收发缓冲、周期发送与本会话日志;后台标签继续收发
- 按会话独立的引擎:序列、脚本、Modbus 主机、录制、宏、发送 DSL、文件传输、回放、设备扫描、自动应答每个标签可各自运行;脚本控制台日志按标签隔离;Modbus 从机 bank 每会话一份;可切标签;关闭忙标签前需先停任务
- 多条循环发送按会话独立:切标签后后台会话循环继续(与定时发送一致);分组列表仍整窗共享
- 后台标签 RX 更新显示/统计,并喂入本会话引擎、自动应答与触发器(绘图 / 组帧 / 仪表盘仍只跟活动标签)
- 序列对话框:结果列跟当前标签;汇总行可看到其它标签正在跑的序列
- 两会话不要共用同一展开后的实时日志路径;需要多份工作台时用「帮助 → 新建窗口」+ profile
IOSSwitch 继承 QWidget,重写 paintEvent 自绘轨道 + 圆点。通过 QPropertyAnimation 配合 pyqtProperty 实现圆点位置的缓动动画(160ms OutCubic)。加了 animate=False 参数让启动恢复状态时不触发动画。
net_io.py 定义统一基类 NetConn(QObject),对外暴露与原串口一致的语义:open()/close()/send(data,target)/is_open + data_received(bytes)/error_occurred/state_changed/clients_changed 信号。三个实现 TcpServerConn / TcpClientConn / UdpConn(组播子类 UdpGroupConn)全部基于 QtNetwork(QTcpServer/QTcpSocket/QUdpSocket),靠 readyRead 等信号事件驱动,不需要自己起轮询线程。主窗口只认 NetConn 接口,因此数据区/发送/高亮/日志等上层逻辑无感。send() 返回写出字节数,SEND_NO_TARGET(-1) 表示无可发送目标(UDP 无对端 / TCP Server 无客户端)。
串口侧 serial_io.py 的 SerialConn 镜像同一套接口(内部封装后台读线程 SerialReader)。主窗口 open_conn() 按「类型」下拉构造 SerialConn 或某个 NetConn,赋给同一个 self.conn,上层对串口 / 网络无感;clients_changed / peer_changed 是网络专有信号,串口连接不发,主窗口按 hasattr 守卫连接。
接收 ASCII 模式时优先 UTF-8 解码,失败回退到 GBK 容错解码,适配国内大部分嵌入式设备的混合编码场景。
新块触发条件(满足任一即触发):
- 方向变了(RX↔TX)
- 时间分包 ON 且间隔 > 超时
- 换行分包 ON 且当前段前有换行符
两个分包开关独立,可单独用也可组合用。例如 Modbus 场景用"时间分包 + 20ms 超时";AT 命令场景用"换行分包 + Auto 模式"。
_pending_line_break 处理跨调用的边界:
- 数据以换行结尾(如
"AT\r\n"),最后一段是空串 → 标志置 True - 下次收到数据强制开新块(即使方向和时间都没变)
- 这样
"OK\r\n"和"AT+CMD\r\n"分两次到达也能正确切成两行
窗口设置 Qt.FramelessWindowHint 去掉系统标题栏,自绘 TitleBar 接管图标 + 标题 + 语言下拉 + 最小化/最大化/关闭。关键技巧:重载 nativeEvent 处理 Windows WM_NCHITTEST 消息,根据光标位置返回 HTLEFT/HTTOP/HTBOTTOMRIGHT 等命中码,让 OS 接管边缘缩放——手感和原生窗口一致,Aero Snap 拖边贴屏也照常工作。
用 QSettings + IniFormat,路径在 exe(打包后)或 main.py(开发模式)同级。saveGeometry() / saveState() 保存窗口几何和 splitter 位置,恢复时按属性一一应用。开关用 animate=False 静默恢复,下拉用 findText 或 index 匹配。
每个主题只定义 4 个核心色 + mode:
"ubuntu": {"mode": "dark", "bg": "#300A24", "fg": "#EEEEEC", "tx": "#3465A4", "ts": "#888A85"}chrome_for(theme_id) 用 _mix() 派生出 19 个 chrome 色:
- Dark 主题:
window_bg = bg,cards / inputs / ghost 按mix(bg, white, ratio)逐级加亮(ghost 14% 比 card 7% 更亮,避免按钮跟卡片同色) - Light 主题:
window_bg = bg(cream / 浅灰),card_bg = #FFFFFF永远纯白,让卡片在主题色窗口上突出浮起
切换主题走 _on_theme_changed:
apply_style()重建全局 QSSfindChildren(QLabel)遍历,按theme_color_role属性(primary/secondary,make_label自动打的)批量刷色findChildren(QWidget)强制unpolish + polish,避免 Qt setStyleSheet 子组件缓存- 启动恢复主题时用
QTimer.singleShot(0, _on_theme_changed)推到 event loop 起来后再刷,规避__init__阶段 setStyleSheet propagation 不彻底的问题
CloseDialog 也接 theme_id 参数,按 chrome_for() 派生自己的 QSS — 关闭对话框跟主题统一。
数据区下拉 8 项:Auto / UTF-8 / GBK / GB2312 / GB18030 / Big5 / ASCII / Latin-1。
- Auto 走原 UTF-8 优先 + 不完整缓存 + GBK 容错回退
- 其他模式走
codecs.getincrementaldecoder(name)(errors="replace")— Python 内置增量解码器自动处理跨包多字节 - 切换编码时 reset
_inc_decoder = None,避免悬挂字节用错误的 codec 解析 - TX 文本发送 / 显示回显 / 文件加载都按当前 codec 处理(Auto 模式 TX 用 UTF-8)
- CRC8 (
0x07):每字节 XOR 进 CRC 高位,移位 + 条件 XOR poly(标准 CRC-8/CCITT) - MOBUS (
0x31):CRC8 变体,多项式不同,国内嵌入式社区把它命名为crc8_ccitt(实际不是真正的 CCITT,只是历史命名遗留) - ModbusCRC16 (
0xA001):每字节 XOR 进 CRC 低位,右移(反向多项式),输出小端(LSB first,Modbus 标准) - CCITT-CRC16 (
0x1021, init0xFFFF):CRC-16/CCITT-FALSE,每字节 XOR 进 CRC 高字节,左移,输出大端 - CRC32:直接调用
zlib.crc32(C 优化,跟 Ethernet/ZIP/PNG 标准一致),输出大端
发送 HEX 模式下,先剥离 /* */、//、# 注释,再去掉 0x 前缀并过滤非 hex 字符,最后交给 bytes.fromhex;下面这些写法都能正确解析:
| 输入 | 解析结果 |
|---|---|
AABBCCDD |
AA BB CC DD |
AA BB CC DD |
AA BB CC DD |
aa-bb-cc-dd |
AA BB CC DD |
AA:BB:CC:DD |
AA BB CC DD |
0xAA 0xBB 0xCC |
AA BB CC |
// 注释\nAA BB |
AA BB |
- v1: 基础串口收发 + iOS 样式 + 持久化
- v2: 中英文双语 + 时间戳分包 + Xshell 风格日志
- v3: 无边框窗口 + 自绘标题栏 + 边缘原生缩放
- v4: 侧边栏布局(USR 风格)+ QGridLayout 右对齐
- v5: 换行分包 + 换行符模式选择(Auto / CRLF / LF / CR)
- v6: 校验算法补全到 9 种(含 CCITT-CRC16 / CRC32 / ADD16)
- v7: 拆分"时间戳"和"分包"为两个独立开关 + 追加换行符模式下拉 + MOBUS(CRC8 poly 0x31)→ 9 种算法 +「无」
- v8: 主控件统一 90px 左右齐平 + 保存/清空按钮也对齐
- v9: 关闭确认对话框 + 系统托盘(最小化到托盘 / 退出 / 取消)
- v10: 图标 base64 固化在源码内(防替换),运行时不再读外部
icon.ico - v11: 多语言扩展到繁体中文 + 鼠标悬停 tooltip + 字号 A−/A+ + 桌面文件夹/onefile/Inno Setup 安装包三种发布形式
- v12: 字符编码下拉(Auto/UTF-8/GBK/GB2312/GB18030/Big5/ASCII/Latin-1)+ 跨包 CRLF 修复 + HEX 严格校验非法字符 + 一次性扫描线程
- v13: 整体主题切换(9 个终端配色方案,全局 chrome 派生)+ 语言/主题下拉挪到标题栏左上 + 关闭对话框跟主题 + 状态点色统一 helper
- v14 (v1.0.1): 高分屏 HiDPI 缩放适配 + 数据区滚动锁定(往上翻定住 / 「↓ 最新」按钮回底 + 自动跟随)+ 单击行高亮 + 切主题历史文字按角色(时间戳/收/发)重涂 + 多条发送弹窗(每行独立 HEX/换行/校验 + 勾选循环依次发)+ 关键字高亮弹窗(每条独立颜色 + 背景/文字 + 收/发/收发范围 + 区分大小写、跳过时间戳)+ 「只显高亮行」过滤 + 弹窗原生标题栏跟随主题深浅 + 波特率补全高速率(256000~2000000)+ 英文标签宽度自适应 + 数据区显示格式统一只看「HEX 显示」开关
- v15 (v1.0.2): 整体界面紧凑化(字号/控件/开关/间距缩小)+ 关键字高亮分组(左侧分组列表,新建/重命名/删除,标题栏下拉选生效分组含「关闭」,编辑与生效独立)+ 多条发送分组 + 每行名称/延时 + 主界面快捷栏([多条发送][▶循环][分组下拉] + 命令平铺直接发,循环按每行延时)+ 实时记录按文件大小分包(不分包/1M~100M/自定义,写满切 _001/_002…)+ 状态栏显示当前日志路径 + 状态栏竖线分隔 + 数据区中文右键菜单(复制/全选/清空/保存,跟随语言)+ 性能优化(编辑去抖、切主题大文档重涂不再卡死)+ 一批审查修复
- v16 (v1.0.3): 工程结构重构(无用户可见功能变化)—— 原 ~4500 行单文件
main.py按模块拆分为main_window / dialogs / widgets / serial_io / theme / i18n / app_icon / icon_data等独立文件;目录分类整理为src/(源码)、docs/(文档)、scripts/(构建/启动脚本 + .iss)、assets/(图标资源),根目录只留 README + requirements + 打包产物;所有脚本与 .iss 路径同步更新(脚本内部cd回根目录,双击即用),打包统一改用py -3 -m PyInstaller - NetworkTool 分支(网络版): 产品更名 NetworkTool,左上角「串口」连接区整体改为「网络」—— 支持 UDP / UDP Multicast(组播)/ TCP Server / TCP Client 四种协议,基于 QtNetwork 事件驱动(新增
net_io.py,移除serial_io.py与 pyserial 依赖);UDP 可选「指定远程」开关(关=回复对端)、TCP Server 多客户端「目标」下拉(含全部广播)、组播地址校验、禁用输入框变灰;数据区/发送/高亮/日志/多条发送/主题/语言等其余功能完全复用。产品与全部打包产物(exe/安装包/dist目录、.iss、%APPDATA%配置目录)统一更名 NetworkTool - v17 (v1.0.4): 在线更新 —— 托盘「关于」对话框新增「检查更新」,从版本清单(内网优先、回退 GitHub 上 NetworkTool 分支 raw)比对最新版,一键下载并弹出安装向导手动升级;更新源 8 秒超时回退(外网不卡)、下载魔数(MZ)校验防错误页误执行、关闭对话框中止在途下载、启动清理
%TEMP%残留安装包、版本号解析容错;基于 Qt 自带 QtNetwork 无新依赖;新增一键发版脚本scripts/release.ps1 - v18 (v1.0.5): 数据区搜索(Ctrl+F:高亮全部匹配 + ▲/▼ 上下跳转 + 实时「N/总数」计数)+ 多屏下状态栏/窗口拖拽/任务栏最小化修复(WM_GETMINMAXINFO 多显示器对齐)+ 深色主题搜索/高亮对比优化 + 系统托盘单击 toggle 显示/隐藏
- v19 (v1.0.7): 稳定性与代码审查修复 —— TCP Client 连接新增超时保护(不可达地址不再卡约 20 秒)、UDP 断开后清理最近对端缓存(复用连接不再回复到旧地址);搜索导航改 O(1) 着色(大文档点 ▲/▼ 不再全文重扫)、打开搜索消除双重扫描、查找栏 viewport/计数标签加守卫、_parse_version 修正预发布版本号比较;修复纯搜索(未配关键字规则)时实时新数据的搜索匹配/计数停更
- v20 (v1.0.8): 修复关键字 / 搜索高亮时,底部新接收的数据会「整批闪一下高亮」的问题(高亮选区不再随末尾插入延伸)
- CommTool 分支(统一版): 串口版 SerialTool 与网络版 NetworkTool 合并为一个产品 CommTool / 通信调试工具。「类型」下拉统一串口 + 网络五种连接(其后增至含 Virtual 共六种;串口
SerialConn与网络net_io共用open()/close()/send()/is_open+ 信号接口,主窗口同一个self.conn);恢复serial_io.py与 pyserial 依赖;品牌、类名、AppUserModelID、%APPDATA%配置目录、安装包 / dist / .iss 全部更名 CommTool(新独立安装 GUID,不覆盖旧版;旧 NetworkTool 配置自动回退读取);发布走 CommTool 分支、tag 前缀comm-v - v21 (v1.1.0): 收发速率 / 包统计——底部状态栏的 RX/TX 由「纯字节数」升级为「字节 · 包数 · 实时速率(B/s)」:包计数(RX = 每次到达一块、TX = 每次成功发送)、1Hz 采样的实时速率、错误数 >0 时追加 ⚠ 标记;鼠标悬停 RX/TX 标签弹出 tooltip 看完整明细(总量 / 包数 / 当前速率 / 峰值速率 / 错误数);状态栏**右键「重置统计」**清零计数器(不动数据区,跟随语言/主题);速率采样常驻、断开后自然归零;三语 i18n 同步、无新依赖、无新文件
- v22 (v1.1.1): 数据波形图 + 协议帧解析两大数据分析功能(标题栏「波形图」「帧解析」)。波形图(pyqtgraph)从 RX 解析数值实时绘多通道滚动曲线,三种解析(分隔符 / 正则 / HEX 字节字段 + 帧头过滤),通道显隐配色、窗口点数、X 轴样本/时间、暂停/清空/导出 CSV、窗口可缩放。帧解析表多帧多规则(规则列表「帧头 | 字段定义」,按帧头前缀匹配),「全部」+ 分规则标签、序号列 + 原始帧列、数值 x 后缀十六进制、hexN/strN、复制/导出、滚动锁定 +「↓最新」回底。二者共用
binproto字段定义。新增依赖 pyqtgraph + numpy(安装包内置);三语 i18n - v23 (v1.1.2): 自动应答全面增强 + 命令历史 + 动态字段 + 自动重连 + 配置档导入/导出。自动应答从 v1.1.1 实验版升级到生产可用:多帧应答(reply 用
|分段顺次发,ACK+DATA 类协议)、HEX 通配??、应答占位符大扩展({rN+K}/{rN^K}/{seq}/{ts})、四种时序控制(整包超时分帧 / 收包校验 / 应答延时 / 触发冷却)、双击按钮一键开关、?帮助按钮带 6 个具体例子。发送区:命令历史 ↑↓ 导航(FIFO 100 跨会话)+ 动态字段{count}/{ts}/{randN}(发送失败回滚 count、N≤256)+ 悬停长寿命 tooltip。连接:自动重连按 1/2/4/8/16/30s 退避(仅对非主动断开生效)。会话配置档导入/导出(数据区右键 + Ctrl+Shift+S/O)一份 JSON 包含 35+ 项设置;导入立即生效,已开弹窗同步刷新。Ctrl+F 全局快捷键任何控件可用。波形图/帧解析顶部?按钮 + 独立说明窗(各 5 例)。InfoDialog 替代 QMessageBox(同主题圆角卡)。5 个子对话框统一parent=None修 Windows 主窗 resize 失效 bug。 - v24 (v1.1.3): bug 修复版(功能同 1.1.2)。①修数据区拖选后新数据到达把选区延伸覆盖刚收到的行(原生文本选区随末尾插入延伸 → append 时按原偏移钉住选区);②修无边框标题栏拖到屏幕顶部外消失、再也拖不回来(拖动加屏幕工作区边界钳制,标题栏始终留在屏内可抓,多显示器适配);③修「检查更新」对话框更新说明过长时被截断、图标顶部被裁(更新说明放进限高滚动区、对话框按内容自适应高度)。
- v25 (v1.1.4): 自动应答「帧头+长度组帧」+ 多条发送增强 + 窗口按钮。自动应答新增第三种组帧:填帧头(如
AA BB)+长度字段偏移/宽度/字节序/整帧固定开销,维护跨包字节流、按帧头定位 + Length 算真实帧边界切分,正确处理串口粘包/拆包(优先于"整包静默超时";binproto.iter_length_frames,自动应答对话框顶部配置、随会话配置档导入导出)。多条发送:名称列↔数据列间加可拖QSplitter(拖一行所有行同步、长名称可拖宽看全)+ 顶部「全选 / 全不选」三态框(反映当前勾选)。多条发送、关键字高亮对话框补最小化 / 最大化按钮。 - v26 (v1.1.5): 自动应答五项增强(校验段 / 规则测试器 / 命中统计 / 故障注入 / 范围延时)。①校验段:每条应答可加 N 段内层/额外校验(对
[起始..结束]算校验、覆盖到指定偏移或追加),在行尾 cs 之前按序计算,配合{rN}占位符回显可自动重算内层 CRC(解决「外层 Sum + 内层 CRC」只能硬编码)。②规则测试器(顶栏「测试」):离线输入一帧 → 看命中哪条规则 + 应答预览(与实发共用组装逻辑、保证预览=实发;不发送 / 不计数 / 不推进{seq})。③命中统计:每行实时「命中 N」+「重置统计」(匹配且收包校验通过即计,运行态、不持久化)。④故障注入(全局框):按概率 丢包 / 错CRC(末字节翻转) / 错长度(砍末字节),专测主机重传与容错,被注入帧数据区留痕。⑤范围延时:延时字段支持100-300(每次发随机抖动,模拟 turnaround)。两框右侧加一句话说明 +?例子帮助窗;三语 i18n;无新依赖;经两轮多代理对抗式评审修复。 - v27 (v1.1.6): 自动应答·多步状态机。弹窗新增「状态机」框(启用 / 初始状态 / 当前状态实时显示 / 重置);每条规则可选 仅状态(when)(当前状态等于它才命中,可逗号分隔多状态、状态名可含空格、空=通配)+ 跳转(goto)(应答发出后切到该状态),把多条规则串成按帧序列推进的握手 / 会话(每行 when/goto 两列仅状态机启用时显示)。离线测试器同步显示当前状态 / 命中后跳转 / 「内容命中但状态不符」提示。工程化细节:goto 仅在应答真正发出后才推进(延时未到 / 断连 / 无客户端 / 发送失败 / 丢包不推进,主机重试仍命中当前状态);带 goto 的应答整条(多段 + 延时)发完前后续帧进有界 FIFO 按收帧顺序处理(杜绝随机延时下状态乱序);断连/重连/切总开关/导入/手动重置回到初始、编辑规则不打断握手。状态机默认关闭,关时与 v1.1.5 行为一致;三语 i18n;无新依赖;经四轮(云端 + 本地多代理)对抗式评审收敛。
- v28 (v1.1.7): 自动应答·Modbus RTU 从机。自动应答弹窗顶栏新增「Modbus 从机」按钮:启用 + 从机地址 + 寄存器表(按「空间 · 起始地址 · 值」配初值,地址支持
0x/十进制、线圈 0/1)。开启后整条引擎作为 Modbus 从机自动应答主机读写——读01线圈/02离散输入/03保持寄存器/04输入寄存器,写05单线圈/06单寄存器/0F多线圈/10多寄存器(写改运行态寄存器、可读回),非法功能/越界地址/非法数据回异常响应(0x80|func+异常码)。组帧:RTU 无帧头 → 按「功能码长度 + CRC 自洽」双重判定切帧 + 跨包缓冲,CRC 不符逐字节重同步(杜绝噪声/错位后永久失步),未知功能码 CRC 探测、0F/10假写多头不阻塞后续合法帧。作 TCP 服务器多客户端时响应精确回请求方(每客户端独立半包缓冲);C6 故障注入仍作用于 Modbus 响应。开启 Modbus 时规则/状态机/帧头组帧让位、弹窗收起这些区块只留故障注入 + 醒目提示条(消除「看着启用却不响应」)。另修暗色主题下复选框看不出选中/未选中(::indicator样式)。新增tests/test_modbus_slave.py(仓库首个自动化测试);三语 i18n;无新依赖;Modbus 默认关、关时与 v1.1.6 行为一致;经云端 + 本地多代理对抗式评审收敛。 - v29 (v1.1.8): 自动应答·位掩码 / 字段级匹配。「匹配」从「逐字节精确 / 整字节
??通配」升级为逐字节 (值, 掩码) 比对(命中需(收到字节 & 掩码) == (值 & 掩码)),支持子字节粒度:半字节通配A?/?5(高 / 低 4 位,X同?)、位级掩码b:+ 8 位0/1/x(x=该位不关心,如b:1xxxxxx1只看最高与最低位);字段级用通配填充到偏移 + 「前缀」模式表达。空格仅作分隔、纯 HEX 跨空格拼接(A B=0xAB,向后兼容);三种匹配模式(包含 / 相等 / 前缀)对掩码同样生效。整字节精确AB、整字节通配??/XX解析结果与改前逐字节等价,旧规则零行为变化;仅 HEX 模式有意义。改动集中在两个静态方法(_ar_parse_hex_pat/_ar_hex_at,仅被实时匹配与离线规则测试器共用),二者自动获得新能力;三语 i18n(占位符 + 帮助补「位 / 半字节掩码」一节);新增tests/test_match_mask.py(17 项,含向后兼容 / 坏格式 / 三模式);无新依赖;经对抗式评审收敛。 - v30 (v1.1.9): 自动应答·脚本应答。每条规则可定义 Python
reply(frame, ctx)动态返回单帧/多帧;ctx 提供状态、序号、命中数和 CRC/校验工具。脚本在独立进程执行,超时整组终止;预览与实发进程隔离;导入含脚本配置前确认信任。新增进程隔离、超时、CRC、配置门禁自动化测试。 - v31 (v1.2.0): Modbus 主机轮询(master / poll)——继自动应答的 Modbus RTU 从机之后,补上 主机侧。数据区标题栏新增「Modbus 主机」按钮,弹窗每行配
名称 / 从机ID / 功能码 / 起始地址 / 数量(或写值) / 周期ms,按各自周期半双工轮询从机(一次只在途一条请求,收响应或超时 1s 再发下一条),实时显示值(十进制 + 十六进制)/ 状态(OK / 超时 / 异常码 / 响应无效 / 发送失败)。读 01 线圈 / 02 离散输入 / 03 保持 / 04 输入寄存器,写 05 单线圈 / 06 单寄存器(周期到点重复写、显示回显)。传输:自动(串口→Modbus RTU、TCP Client→Modbus TCP)或强制选择。本地回显模式:串口适配器回显发出帧时勾选——剥掉前导回显(容忍噪声/残留)再解析真实响应,专治 05/06 回显与「写成功」同形导致异常被吞。响应严格核对从机ID / 数量 / 写回显 / 异常功能码匹配;RTU 坏帧丢 1 字节重同步(不清整缓冲,杜绝本地回显粘包丢响应),TCP 按 MBAP 自分帧。新增纯逻辑src/modbus_master.py+ 对话框src/modbus_master_dialog.py+tests/test_modbus_master.py(34 项);三语 i18n;无新依赖;启用前不影响原有行为;经三轮对抗式评审收敛。 - v32 (v1.2.1): Modbus 主机增强 + 误操作安全 + 表格交互。①写功能码补 0F 写多线圈 / 10 写多寄存器(「数量/写值」格填逗号或空格分隔的多值,如
100,200,300;0F 线圈填 0/1)。②误操作安全(经多轮对抗式评审收敛):非法/越界 从机ID(0..247)/起始地址(0..65535)/写值 一律拒发而非静默钳位(杜绝非法 ID 变广播地址 0 误写所有从机);写多任一项非法或超规范上限整组拒发(不静默截断/前移地址);写功能码异常响应严格核对原功能码;响应超时静默期——超时后短暂不发下一条,避免迟到响应被误配对到下一行。③草稿编辑:启用轮询时编辑规则只进草稿、不再 300ms 自动提交并发送,须点**「应用」才生效(防读切写时误发);未应用草稿关窗重开保留。④表格**:名称~值七列放进可拖QSplitter,列边界可左右拖宽、所有行+表头像素同步,功能码列变窄。⑤健壮性:单条规则损坏只跳过不清空整表;字符串"false"正确识别为停用;大量非法规则异步排程不再递归致栈溢出;主机轮询激活时跳过自动应答,防与内置 Modbus 从机互发干扰;自动应答与 Modbus 主机一键互斥(开一个自动关另一个、UI 同步)、TCP/串口半帧写入即时断流重连不污染后续帧、Modbus 数值输入兼容前导零(如08/010)。tests/test_modbus_master.py增至 60+ 项;无新依赖;经六轮对抗式评审收敛。 - v33 (v1.2.2): 多条发送拖拽排序 + 自动检查更新。①多条发送拖拽排序:每行行首加 ☰ 拖拽手柄,按住上下拖即可改变发送顺序、松手立即落盘;按落点上半/下半自动定位插入点(
_DragHandle发起QDrag+ 列表容器eventFilter接 drop 重排_rows)。②自动检查更新(类 Claude 的静默提示):启动后台静默查一次 + 之后每 6 小时再查(复用 v1.2.1 的 urllib + 系统证书检查器);命中新版才提示、无新版/网络不通全程静默不弹框;发现新版时右下角版本号变「● 可更新 vX」高亮可点徽标,点击直接打开「关于」走下载安装;「关于」对话框新增 「自动检查更新」开关(默认开,可关闭、仍可手动「检查更新」,随会话配置档导入导出)。i18n 加update_badge/update_badge_tip/auto_check_update三语;经三轮 review 收敛(拖拽手柄事件透传、DragLeave处理、空版本号边界防御);headless 端到端测过 + 原回归全过;无新依赖。 - v34 (v1.2.3): 串口稳健性 + 对话框列宽记忆(修复版)。①串口选择防乱跳:选中口被后台扫描偶发瞬时掉枚举时不再静默跳到别的口(去抖宽限内保留「未检测到」占位);口长期不在则自动删占位、回落第一个真实口(修了「列表稳定后缺失计数停更、占位删不掉」的回归)。②已连接串口被移除(拔出/掉驱动)连续几次检测不到 → 自动断开 + 提示「串口 X 已移除」。③串口掉线不再自动重连(物理事件、重连可能连错口;网络 TCP/UDP 仍按退避重连)。④三对话框列宽持久化:「多条发送 / Modbus 主机轮询 / 自动应答」拖动调整的列宽写入 settings(
multi_send_split/modbus_master_split/autoreply_split),重开/重启保持、随会话配置档导入导出。⑤另修:启动扫描早于配置恢复时仍能选回上次串口(pending 不被「列表没变就 return」跳过);连接出错处理改用_conn_proto(实际连接协议)判断,避免连接中导入配置误判。tests/test_script.py增至 58 项;无新依赖。 - v35 (v1.2.4): 终端模式(轻量串口终端)。「发送区」设置新增「终端模式」开关,开启后:①逐字符即时发送——发送框作键盘捕获,每个按键即时转字节发给设备(回车 / Backspace / Tab / Ctrl+C / 方向键 ↑↓←→ / ESC / Home / End / Delete 透传,
_term_key_to_bytes映射 + eventFilter 拦截直发)。②轻量 VT 渲染——数据区按终端语义显示设备回显:\b光标左移 + 覆盖式打印、\r回行首、\n换行,并解析行编辑常用 CSI(ESC[J/ESC[K擦除、ESC[C/ESC[D光标);颜色ESC[..m等其它 CSI 忽略(带颜色输出显示干净、无^[[乱码);跨数据块拼接 + 光标位置延续;CSI 缓冲 64 字符上限 + 无终止符洪水跨块丢弃防护。③本地回显 / 回车映射——「本地回显」开关 + 「回车」CR/LF/CRLF(默认 CR)。④开启时淡化禁用用不上的格式设置(HEX 显示/时间戳/分包/超时/HEX 发送/校验等,标签+控件整行淡化,IOSSwitch 禁用态变淡)、停掉定时发送;关闭恢复。三项随会话配置档导入导出、即时生效(terminal_mode/terminal_echo/terminal_enter)。i18n 三语;经六轮 review 加固(占位同步 / 导入重载 / 定时停止 / 标签字典防覆盖 / 大计数防冻 / 坏 ini 安全解析 / CSI 洪水);tests/test_script.py增至 66 项;无新依赖。局限:不解析全屏 TUI(vi/top)。 - v36 (v1.2.5): 多窗口(独立配置)。可同时开多个独立窗口、各调各的设备、互不干扰。①新建窗口:「帮助 → 新建窗口」
subprocess.Popen起新进程(冻结版起 exe / 源码起 python+main.py);标题 / 任务栏 / 托盘带(2)/(3)后缀。②配置隔离:_settings_file(profile)主=settings.ini(含旧路径兼容)、其余=settings-<N>.ini;启动时main._acquire_profile()用QLockFile挑第一个空闲槽位(主/2..8;开满 8 个则提示"已达上限"、不再新建,不用 PID 建菜单管不到的孤儿配置)并持锁到退出——双击开多个 / 新建窗口都自动分到不同配置,退出不再互相覆盖(解决"开两个窗口配置冲突");槽位释放后可被下个窗口复用。③各自独立:连接 / 收发 / 自动应答 / Modbus / 终端等状态本就挂在各自进程,天然隔离(同一串口仍只能被一个窗口打开)。④多显示器兜底_ensure_on_screen:首次显示后窗口若不在任何屏幕内(旧位置落到已断开的屏)→ 搬回主屏,避免"进程在、窗口看不见";新窗口无保存位置时按 profile 序号层叠偏移防重叠。⑤更新临时包多窗口加固:cleanup_temp_installers跳过近 10 分钟改动的文件、下载文件名加 PID,避免多窗口互删/同写。⑥打开配置(切换)/ 删除配置:「帮助 → 打开配置」子菜单列已存配置,点空闲的_switch_profile就地把当前窗口切到该配置(抢锁 → 存当前 + 断连 → 换 settings/标题 →_apply_loaded_settings重载 → 保窗口几何;被别窗口用的 / 当前窗口的禁用);「删除配置」_delete_profile删 2..8 空闲配置(QLockFile独占确认无人用 + 二次确认、确认框默认焦点「取消」防误删);--profile=<N>命令行 +_acquire_profile(preferred=)支持指定槽位。⑦关键修复:① 开着系统代理时 Qt socket 被套 HTTP 代理致本机/局域网 TCP 连不上 →main全局QNetworkProxy.setApplicationProxy(NoProxy)一律直连(TCP/UDP 全实测通);② 状态栏showMessage提示与 RX/TX 统计文字重叠 → 状态栏底色transparent→不透明window_bg擦底;③QLockFile与QSettings撞锁自死锁致多窗口开第二个卡住只剩进程没界面 / 关窗卡死 → 槽位锁后缀改.mwlock(与 QSettings 内部.lock区分);④ 切换配置时旧连接残留 / 缺失字段继承上一配置。i18n 加new_window/open_profile/profile_current/profile_busy/profile_switched/delete/delete_profile/profile_delete_*/new_window_auto/max_windows;.gitignore加settings-*.ini/*.ini.lock/*.mwlock;tests/test_script.py全量增至 164 项(配置隔离 / 锁抢占复用 / 自死锁回归 / 切换 / 删除 / 白名单 / 满窗上限 / 状态栏不透明 / 屏幕外搬回,均隔离不受运行窗口影响);无新依赖。 - v37 (v1.2.6): 自动化测试序列。菜单栏「功能 → 自动化序列」新增一个把「发送 → 等回包匹配」步骤按顺序自动跑一遍、逐步判定通过 / 失败并出汇总的功能,适合出厂测试、设备自检、批量验机、协议联调等重复动作。每步可配 名称 / 发送内容(文本 / HEX)/ 校验(CRC / 累加和等自动追加,同主界面)/ 期望回包(留空 = 纯发送不等回包)/ 匹配模式(包含 / 相等 / 前缀)/ 超时 ms / 超时动作(停止 = 失败即整体结束、继续 = 记失败但往下跑)/ 步间延时 ms / 启用勾选;按顺序发送每步、等回包并按匹配模式判定,结果列实时 待运行 → 等回包… → ✓ 通过 / ✗ 超时,全部跑完出汇总。序列是主动驱动方(与自动应答、Modbus 主机共用收流),运行期间自动暂停自动应答 / Modbus 主机、结束自动恢复;连接断开中止序列并保留已跑结果。UI:卡片式每步一行,只有「发送」「期望回包」两个数据框可拖宽、其余列固定(形制同自动应答对话框);带「?」用法说明弹窗(含 AT 指令 / Modbus 读寄存器 / 纯发送三个示例);运行中「运行」按钮变绿并锁定增删行、结果列实时更新,步骤自动保存。
tests/test_script.py增至 181 项;无新依赖。 - v38 (v1.2.7): 自动化序列可上产线(报告导出 / 循环老化 / 步骤重试 / 导入导出)。在 v1.2.6 序列基础上补齐上产线要素。①测试报告导出(HTML / CSV):跑完点「导出报告」出 HTML(通过/失败底色 + 汇总结论 + 测试时间,可存档/发邮件)或 CSV(Excel 可开、已防
=/+/@公式注入);循环运行出「按轮次」表、单次出「按步骤」表;仅正常收尾(有汇总)才可导,停止/断连的残缺结果不导成缺结论报告。②循环运行(老化 / 可靠性测试):顶栏「循环」次数(≥1,引擎钳_SEQ_MAX_LOOPS=10万)+「失败即停」,让设备连续自检 N 轮做老化;运行中显示 第 R/N 轮 · 第 i/n 步,汇总给「通过轮 R/N + 累计步 X/Y」、提前停止标「计划 M 轮」防误读;轮间singleShot(0)让出事件循环、代际作废残留;中途停止/断连也为已跑轮出汇总(stopped=True一律非 PASS)、结果可导。③步骤级重试:每步「重试」次数(0=不重试,引擎钳999),失败(超时/发送失败)后等本步延时 + 线路连续静默 50ms 再重发、任一次通过即过、结果标「(第N次)」;耗时含所有尝试;上次尝试的迟到响应不污染下次匹配(retry 态字节只延长静默窗),静默等待有 2s 上限防对端狂刷卡死;重试窗被停止/断连标stopped并保留 attempt。④步骤导入 / 导出(JSON):「步骤 ▾」导出/导入整条序列便于分享/版本管理用例;导入严格校验(1–500 步、字段类型与范围、限 5MB)、覆盖前二次确认;timeout/delay钳 QTimer int 上限防 JSON/旧配置绕过 UI 校验器。tests/test_script.py增至 195 项;三语使用文档补 v1.2.7 章节;无新依赖。 - v39 (v1.2.8): 帧构造器。功能菜单新增按字段拼帧:支持带大小端的数值、ASCII、原始 HEX,以及自动长度和 ADD/XOR/CRC 校验;内置 Modbus 读、Modbus 写单、AT 模板,实时预览完整 HEX,可填入发送框或直接发送。字段行可拖拽排序、列宽可拖、配置自动保存;直接发送按构造结果原样发出,填入发送框后仍遵循主界面可见的换行/校验设置。数据区同时修复"有选区且向上翻看时,新数据把视图拽走"的滚动回归;无新依赖。
- v40 (v1.2.9): 工具箱 + 功能菜单重组 + 串口控制线 + 文件传输 + HEX 转储(一次多项实用增强)。①工具箱(功能 → 工具箱):进制/编码转换(字节序列 HEX ⇄ 文本 ⇄ 十进制 ⇄ 二进制实时互转、按 ascii/u16/i16/u32/i32/f32 解释、单值多进制 + 位掩码)+ 校验计算(一次列出全部内置算法结果反推设备用哪种 + 自定义 Rocksoft CRC)。②功能菜单重组:波形图 / 帧解析 / Modbus 主机 从数据区工具栏移入标题栏「功能」菜单带序号统一排列,工具栏精简(只留高亮 / 字号)。③串口控制线:打开串口后「打开串口」下方出现小节——DTR / RTS 输出开关、复位(DTR 拉低 ~120ms 触发 Arduino/ESP 自动复位)、中断(Break)(拉低 TX ~250ms)、CTS/DSR/DCD/RI 只读状态灯(~5Hz 轮询);串口设置加「流控」下拉(无 / RTS-CTS 硬件 / XON-XOFF 软件)。④文件传输(功能 → 文件传输):XMODEM(128B 校验和/CRC)/ XMODEM-1K / YMODEM 收发双向(常用于向 bootloader 上传固件)+ 原始字节流(按可配分块大小 + 块间延时直接发送);进度 + 日志 + 取消,传输期暂停数据区显示 / 自动应答 / 序列 / Modbus。⑤HEX 转储视图:数据区显示新增「HEX 转储」开关,收发按 hex 编辑器风格渲染 偏移(8 位) + HEX(每行 8/16/32/64 字节可选、半程加宽)+ |ASCII| 三列,与「只显高亮行」过滤联动、时间戳装饰行始终可见。
tests/test_script.py增至 227 项;三语使用文档补 v1.2.9 章节;无新依赖。 - v41 (v1.3.0): 桥接转发(两端任意 串口/TCP/UDP 双向透传)。功能菜单新增「桥接」:A/B 两端各自独立选 串口 / TCP客户端 / TCP服务端 / UDP,连通后双向原样透传字节,支持串口↔串口 / 串口↔网络 / 网络↔网络任意组合。①引擎(
src/bridge.pyBridgeEngine,纯信号驱动无独立线程):连双方data_received双向send转发、监听state_changed/error_occurred任一侧断开或出错自动停桥、1s 滑窗实时速率 + A/B 收发计数、按具体 slot 断信号不误伤面板槽、stats_updated用 object 型防长桥接计数溢出。②发送加固(net_io的send_bridge/bridge_ready):TCP 服务端多客户端广播 + 4MB 待发缓冲背压(部分写判帧损坏踢客户端)、UDP 按 65507 拆合法数据报、发送失败边沿触发上报(进日志不刷屏、不静默丢数据)、开桥前bridge_ready预检(TCP 需已连接 / UDP 需有对端)。③对话框(src/bridge_dialog.py):4 类型逐侧配置、TCP 连接中「取消」态、转发日志(文本/HEX、增量 UTF-8 解码防跨包乱码、单条 4KB 上限、由forwarded仅成功转发驱动)。④对话框 UI 修复(dialogs.py):所有对话框下拉补下拉箭头、禁用输入框变灰;桥接「指定远程」改用 IOSSwitch。tests/test_bridge.py引擎单测 20 项(全量增至 247);三语使用文档补 v1.3.0 章节;无新依赖。 - v42 (v1.3.1): 数值仪表盘 + 协议高亮 + 串口自动重连 + USB 芯片识别(一次多项实用增强)。①数值仪表盘(功能 → 数值仪表盘,
src/dashboard_dialog.py+src/stream_parse.py):把 RX 流按 分隔符/正则/HEX 字段 解析成命名数值通道(解析器抽成 Qt-free 的NumericStreamParser,增量解码器防跨包多字节截断、切编码清残段),每通道一张大字号卡片(FlowLayout自动换行)实时显示当前值,阈值行名称:下限~上限:单位超限卡片变红 2Hz 闪烁;卡片数上限 64、暂停/隐藏切断解析残段、配置(dash_*)与波形图独立。②协议高亮(src/main_window.py+frame_dialog.py):帧解析对话框勾选后,HEX 显示模式下按frame_rules把收到帧各字段映射成数据区字符区间上色(复用 ExtraSelection 管线、字节→字符pos+3*off)+ 悬浮「规则·字段=值」;仅普通 HEX 生效(切文本/转储即撤、立即重画)。③串口自动重连(src/main_window.py):串口运行时掉线保存完整签名_serial_reconnect_cfg,退避 0.5s 线性递增到 5s、只open_conn(reconnect_cfg=)回原设备/原参数(不读可能漂移的下拉框)、等原口重新枚举进_available_serial_devices才试、原口一出现即timer.start(0)秒连;等待缺口与真实打开共用单一 10 时隙预算(约 27.5s)静默放弃、防第 10 次失败退化成 UI/网络重连;_reset_recv_state(reset_dashboard=)区分显示切换与真断点。④USB 芯片识别:串口下拉在系统描述后按 VID/PID 补 USB-UART 芯片型号(CH340/CP2102/FT232 等)。tests/test_script.py增至 281 项;三语使用文档补 v1.3.1 章节;无新依赖。 - v43 (v1.3.2): 脚本控制台 + 宏录制 + 收发任务统一互斥(把自动化从 GUI 配置推进到代码级可编程)。①脚本控制台(功能 → 脚本控制台,
src/script_console.py+src/script_console_dialog.py):用 Python 脚本驱动当前连接的真实收发,APIsend/recv/expect/sleep/log/check/hexs;执行核心ScriptWorker(QThread)—— 脚本要send();r=expect()顺序阻塞驱动连接,子进程碰不到连接对象故用线程,worker 只碰 deque/Condition/信号、发送经信号回主线程;收包有界缓冲(feed 入口就限流 1MB,脚本 sleep 时设备狂刷不撑爆内存)、发送握手式背压(一次一个在途 + worker 身份校验,停止/换轮的旧 worker 不会把积压数据发到新会话)、停止为协作式(send/expect/recv/sleep 检查点);多脚本库(≤50)随配置持久化、JSON 导入导出走信任门禁。②宏录制(src/macro_recorder.py,Qt-free 可单测):录下主界面手动收发并翻译成脚本 —— 每次发送出send(...)、其后回包合并成expect(...)+check(...)(超时按实测延迟留 3 倍余量)、间隔 ≥50ms 补sleep(ms)保留节奏,可打印字节用字符串字面量否则hexs(..),生成代码保证可编译;只录「用户手动发」——脚本自身 send、自动应答/Modbus 从机回复(_ar_in_flight)、序列/定时/多条循环(record_macro=False)全排除,采集判定收敛到_macro_record_tx单一入口。③收发任务统一互斥(_io_task_busy):单一占用表(脚本/序列/传输/宏/定时/多条/Modbus)+ exclude 白名单,6 个启动入口共用,根除「各写一套互斥条件、漏项」;_manual_send_blocked在独占回包期间禁止手动发送插入线路;脚本接管时取消 Modbus 在途请求并隔离一个完整超时窗(_script_quiet_until)避免旧响应污染首个 expect。④功能菜单分组:帧处理(1-3)/可视化(4-5)/自动化(6-7)/通信传输(8-10) 加分隔符、Modbus 仍末位;一次性菜单经_exec_transient_menu回收不再累积为主窗常驻子对象。⑤对话框下拉框修复:弹出层QComboBoxPrivateContainer显式刷底色(不设背景时 Windows 原生 palette 会在开合瞬间透出系统强调色)。tests/test_script.py增至 343 项;三语使用文档补 v1.3.2 章节;无新依赖。 - v44 (v1.3.3): 虚拟连接 + 数据录制/回放 + 命令 DSL(围绕「没有硬件也能干活」)。①虚拟连接(
src/virtual_io.py,「类型」下拉新增Virtual):接口与串口/网络完全一致,故自动应答 / 序列 / 脚本 / 波形图 / 仪表盘 / 协议高亮全部直接可用、无需各自改造;「回环」开关把自己发出的数据当成收到的回来,可离线验证规则与脚本;回环与注入一律经 0ms QTimer 派发到下一轮事件循环——同步 emit 会在_send_text尚未返回时重入收包路径。②数据录制/回放(src/rec_replay.py+src/rec_replay_dialog.py):录线路原始收发流含时序存.ctrec(JSON Lines,可读可 diff,坏行跳过而非整体失败);回放按原节奏重新注入,可调倍速/循环/含 TX;大块收包按同一时间戳拆事件而非截尾(录的是原始流,静默丢字节会让复现失真);单 tick 派发上限 1000防「最快」模式一次排队几十万个 Qt 回调卡死 UI;载入校验版本/时间戳/事件数/文件大小;回放落点只接受虚拟连接(往真实串口注入「收到的数据」物理上不成立)。③命令 DSL(src/send_dsl.py):发送框支持\!(Delay500)/\!(Wait50)/\!(Repeat3)/\!(Hex)/\!(Text),不含指令时完全走原发送路径、行为一字不变;编译成指令序列后由 QTimer 逐条执行不卡界面,发送失败/断连立即中止并作废已排队回调,次数/延时/展开条数三处上限;\\转义不当指令。④任务互斥扩展:录制/回放/DSL 纳入_io_task_busy统一占用表,_manual_send_blocked期间禁止手动发送插入;功能菜单自动化组加「数据录制 / 回放」,Modbus 主机仍末位。⑤发送框悬浮提示补 DSL 一节,并加测试把「提示里的示例必须真能编译」锁死(防改语法忘改文档)。tests/test_script.py增至 406 项;三语使用文档补 v1.3.3 章节;无新依赖。 - v45 (v1.3.4): 数值视图 + 选中即算校验和 + 动态改串口参数 + 日志增强 + 会话比较(围绕「看得更清、改得更快、比得出差异」)。①数值视图(
src/convert.pyformat_numeric+src/main_window.py):显示设置新开关,字节流按 u8/i8/u16/i16/u32/i32/f32 × 大小端 12 种组合解读成数值序列,看 ADC/传感器原始值不必手动换算;尾部不满一个数的字节留到下一包续拼、跨包不错位(TCP Server 按客户端source分桶隔离余数、断开自动回收),列宽按类型写死使多包纵向对齐;与 HEX 转储互斥(互相灰掉、配置两者同 True 时归一化为转储获胜)、数值视图下协议高亮让位。②选中即算校验和(src/convert.pyselection_to_bytes+ChecksumPopup):数据区选中一段字节,状态栏就地出 Modbus/XOR/SUM、悬浮弹全 9 种校验的主题化卡片(行控件复用不重建,避免连续悬停 QLabel 堆积);字节还原按正文 fragment 的视图标记,自动跳过时间戳/箭头/转储偏移与 ASCII 列、切视图后回看历史数据仍按当时格式解析,文本/数值/终端视图不可无损还原则整段拒算;提取与计算全链路有界(行内 limit 提前收工 + 上限 16KB,全选百万行不卡界面),半个 HEX token 丢弃不猜值。③动态改串口参数(src/serial_io.pyapply_params):连接期间改波特率/数据位/校验位/停止位/流控即时应用到活动串口、不断开不丢接收缓冲;参数原子应用,中途赋值失败回滚已改属性到调用前快照,不留「硬件跑混合参数」半应用态;信号只挂activated/editingFinished避开手输逐字符与程序化 setCurrentText 误触发,应用成功同步_conn_cfg连接签名真源(Modbus 就绪门禁/RTU t3.5/掉线重连都读它)。④日志增强(src/log_naming.py,Qt-free):实时记录文件名支持%date/%time/%datetime/%port/%n变量、未知%x原样保留;含日期变量时跨自然日自动开新文件、序号归零(按天归档),变量可出现在目录段并自动建目录,与原有按大小分包_001共存。⑤会话比较(src/rec_diff.py+src/rec_diff_dialog.py,功能菜单第 9 项):选两个.ctrec逐条对齐比出 相同/内容不同/仅A有/仅B有 并报时差;对齐用 Hirschberg 线性空间 LCS(内存从朴素 DP 的 O(n·m) 降到 O(min(n,m)),3000² 约 70MB→约 2MB),某边少一帧只报一处、后续不整体错位;退化按格子数 n·m 判定(上限 50 万格)而非条数、超限退化成按下标并排并标degraded不悄悄截断;_lcs_ops出口归一化删增顺序 +_pair_ops块内逐条配对使连续多帧变更都合并成 diff;时间不参与是否相等的判定、只在配对后报偏差,CSV 导出防公式注入,空录制(0 事件)按是否选文件判定可比较。⑥风格统一:会话比较的「?」帮助改自绘主题窗(对齐录制/回放)、载入/导出失败改用主窗 toast,rec_diff_dialog不再依赖QMessageBox。tests/test_script.py增至 520 项;三语使用文档补 v1.3.4 章节;无新依赖。 - v46 (v1.3.5): ANSI 彩色显示 + 触发告警 + 发送模板库 + 显示方式整合(围绕「日志更像终端、异常主动提醒、常用命令随手取用」)。①ANSI 彩色显示(
src/ansi.py,Qt-free):解析 SGR 基础色/亮色/256 色/真彩与粗体/下划线/反显,深浅主题用独立可读调色板;样式和未完成转义序列跨包延续,TCP Server 按客户端隔离,超长控制串有界丢弃;光标控制、窗口标题等非 SGR 序列直接吃掉,文本显示与终端模式均接入,切主题时历史文字按颜色标识重解析。②触发告警(src/triggers.py+src/triggers_dialog.py):支持包含/相等/前缀/正则及文本/HEX 匹配,范围可选 RX/TX/收发;命中后响铃、托盘通知、数据区打标,冷却仅抑制动作而命中次数/最后时间照常累计;串口/TCP 连续流支持跨块关键字与半字符,UDP 保持数据报边界,TCP Server 按客户端隔离尾巴;正则预编译并拒绝明显灾难性回溯结构。③发送模板库(src/snippets.py+src/snippets_dialog.py):在多条发送窗口一键打开,保存常用文本/HEX 命令,支持模糊搜索、增删、JSON 导入导出、双击填入或直接发送;最多 500 条、字段有界、编辑去抖落盘,空库/字符串布尔值/切行与搜索重建均有回归保护。④显示方式整合:文本/HEX/HEX 转储/数值四种渲染方式合并为互斥下拉,附属设置随模式切换,避免旧开关出现多个模式同时为真的冲突态。tests增至 628 项;无新依赖。 - v47 (v1.3.6): 工作台工程化 + 设备定义 / Modbus 扫描中心 + 结构化数据记录 + 工程资源包。①工作台按终端、协议、仿真、自动化、数据、桥接分页,工程菜单提供新建、打开、保存、另存为、最近工程与启动恢复。②设备中心维护寄存器标签、类型、字节序、倍率、偏移和单位,可扫描 Modbus 从机地址或 03/04 寄存器区间;扫描临时接管原主机调度、保护在途 RTU 响应、锁定配置编辑并在结束后恢复内存和持久化状态,单批最多 512 项。③结构化记录将 Modbus 标签和协议字段保存为可筛选、CSV 导入导出、按时间轴回放的数据。④
.ctprojv2 显式打包寄存器表、模板、分组、序列、脚本和仪表盘配置,兼容 v1;旧工程缺少寄存器表/模板资源时会按工程空资源初始化,需保留当前内容请先导出或另存 v2。同步更新三语用户文档与发布说明;无新依赖。 - v48 (v1.3.7): 具名连接预设 + 序列变量 / CSV 数据驱动 + JUnit 测试报告 + 统计诊断增强 + Modbus 专业化 + 回放与差异分析(把「设备预设 → 自动化测试 → 报告导出」串成闭环,并把 Modbus 模拟与记录回放做深)。①连接预设(
src/connection_presets.py+src/connection_presets_dialog.py,核心 Qt-free 可单测):具名保存串口/网络全部参数、备注与自动重连策略,normalize/sanitize 规整任意来源数据、同名 upsert 覆盖、复制/删除、MRU 排序与 JSON 导入导出;连接栏加预设下拉 + 保存/管理,已连接时拒绝应用并回退占位项,空ser_port预设会清空当前串口选择,应用后 MRU 重排同步刷新管理窗下标避免后续操作打到错项;预设纳入.ctproj工程资源(connection.presets)与 QSettings 持久化。②序列变量与上下文(src/seq_context.py):步骤 send/expect 支持${name}展开、$${转义为字面${,回包提取器支持 text / hex / regex / modbus 与紧凑 DSL 双向转换,每轮独立RoundContext;未定义变量不再静默降级成纯发送而是当步失败(seq_st_var_missing),避免循环老化假阳性。③CSV 数据驱动序列(src/sequence_dataset.py):绑定 CSV 后每行跑一轮、表头作${var}种子、轮数取行数,行标签按device_id/sn/name等列优先取;编码按 utf-8-sig → gb18030(Excel/GBK)→ latin-1 回退,行数/列数/单元格长度与文件大小均有界。④测试报告与 CI 产物(src/junit_report.py,Qt-free 可单测):导出新增 JUnit XML(testsuites/testsuite/testcase + properties + failure/skipped + system-out),HTML/CSV/JUnit 统一补充软件版本、开始与结束时间、测试参数(轮数、步骤数、失败即停)与 CSV 路径,每步记录耗时、失败原因和关键收发帧(TX / RX HEX);中途停止或断连改为一律出汇总并可导出(标记 stopped 且保留已抓到的收发帧),多轮报告逐轮展开每步明细,无完整轮次时三种格式统一回退到逐步骤表;XML 按 XML 1.0 规则净化控制字符(否则 CI 侧解析直接失败),CSV 的标题、元信息与汇总行也走公式注入防护。⑤统计与诊断增强(src/io_stats.py,Qt-free 可单测):包速率 pps、包大小 min/avg/max 与分布直方图、峰值速率与峰值包速、序列 / Modbus 主机 / 连接三类超时计数、约 3 分钟吞吐历史;所有 RX/TX/错误统一经_stat_note_*入口同时更新旧计数器与累加器(部分写入按底层实际字节数计入、不计包数),状态栏展示 pkt/s、悬浮提示展示分布与超时,波形图可订阅rx_Bps/tx_Bps/rx_pps/tx_pps,重置统计不影响记录与数据区。⑥多从机模拟(src/modbus_slave.pyMultiSlaveBank+slave_bank_from_config):同一条总线上按 JSON 配多个从机,各自寄存器表 / 从机 ID,未填项按顶层继承(_merge_slave_cfg),非空slaves覆盖单地址表;slaves为空数组或全非法条目时回落单从机,广播地址 0 只放写功能码、读与 0x08/0x0B/0x11/0x17 一律拒绝,TCP Server 仍按客户端隔离半包缓冲;对话框里slaves文本能解析但不是数组时报错拒绝,不再静默丢掉原有多从机配置。⑦异常注入与动态寄存器(src/modbus_dyn.py,Qt-free 可单测):ExceptionInjector支持always/once/n三种模式并按funcs/addrs过滤(FC23 的读段与写段起始地址都参与匹配,且一次调用只算一次命中,不重复消耗 once/n 计数);DynamicEngine支持inc/dec/random/sine/ramp,主机写入形成 sticky override 直到reset(),reset()会重建带seed的 RNG 并清掉 random 的周期标记使序列真正回到开头。⑧补齐功能码(src/modbus_master.py/src/modbus_slave.py):主从两侧支持 FC08 / FC11 / FC17 / FC23(0x08 / 0x0B / 0x11 / 0x17),rtu_normal_len按功能码给帧长(01/02 按ceil(qty/8)、0x17 按读数量、0x11 给 256 只作超时预算),0x11 变长响应在 RTU 按字节数字段、TCP 按 MBAP 长度取帧,未知功能码退回 CRC 探测重同步;FC08 子功能 0 校验回环数据是否与请求一致、结果同时给十进制与十六进制,FC23 写地址走轮询表读数量 @ 写地址 : 写入值紧凑语法并纳入.ctproj,normalize_poll对write_addr与diag_sub保证幂等(缺键才回退默认,配了但非法保持 None 让上层报错),越过 0xFFFF 的连续读写在轮询前就按「参数非法」拦下。⑨图表持久化与结构化回放(src/rec_replay.py+src/structured_record_dialog.py):图表数据源 / 单位 / 布局随工程保存,结构化记录按原时间轴回放驱动同一套图表;Player支持暂停、单步、倍速、循环与按秒定位,pause(now)强制传入单调时钟避免墙钟跳变,step()自动先暂停保证一次只前进一个事件,seek()保持原播放态,暂停 / 单步 / 定位控件仅在回放中可用。⑩会话差异筛选与导出(src/rec_diff.py+src/rec_diff_dialog.py):按方向与时间差绝对值筛选,汇总计数按筛选后可见行统计,筛选结果可导出 CSV/JSONL,筛空时导出按钮禁用不产出只有表头的文件。tests增至 872 项 + 288 项子测试(新增tests/test_modbus_dyn.py、tests/test_rec_replay.py、tests/test_io_stats.py、tests/test_junit_report.py与tests/test_p1_*.py系列);同步更新三语用户文档的 v1.3.7 章节与发布说明;无新依赖。 - v49 (v1.3.8): Tooltip 自动换行 + Modbus 异常注入/动态寄存器/FC08 配置界面 + 波形双击跳转会话时间(收尾 1.3.7 体验与配置缺口)。①统一
ui_tips.set_tooltip让长提示自动换行,托盘 tip 保持纯文本;②从机对话框补齐异常注入模式/过滤、动态寄存器表与server_id,主机 FC08 数量列支持子功能:数据并在切功能码时刷新 tooltip;③波形图双击按 wall 时间调用jump_to_session_time(速率通道不跳转);④修复动态max=0被写成 65535、自动应答重复closeEvent导致 split 尺寸不刷盘、帮助文案过时等。全量测试 887 passed / 4 skipped;无新依赖。 - v50 (v1.3.9): 多从机行表 UI + 状态栏/会话比较跳转会话时间 + 数据区书签(收尾 P1)、①从机对话框用 Addr/Server ID/Extra 行表替代 JSON,重复地址拒绝;②状态栏 RX/TX 与会话比较双击行接通
jump_to_session_time(.ctrec写wall_t0);③Ctrl+F2/F2/Shift+F2书签,清屏/ANSI 全清一并清除;④整理 TODO/三语文档过时表述。无新依赖。 - v51 (v1.4.0): 正式版 — 64 位寄存器 / 位域 / 告警级别 + Modbus 多视图与 FC22/FC43 + Webhook / 外部程序触发动作 + Modbus TCP↔RTU 网关;地址基与阈值贯通;网关多客户端定向回包、超时恢复窗口防迟到串扰、同批重同步不丢合法帧;外部程序进程组回收(单动作最长 30s)、触发删除确认、SSRF 字面量私有地址拦截;1023 passed / 3 skipped。
- v52 (v1.4.1): 正式版 — S-2 主窗口可维护拆分(R1–R42) + S-1/S-3/S-4/S-5 稳定性与易用性;服务层与 GUI build_* 工厂迁出;空 JSON 列表/字典解析、发送历史导航、未使用导入等修复;1148 passed / 4 skipped / 291 subtests。
- v53 (v1.4.2): 正式版 — S-2 R43–R55 运行时/显示/设置/连接抽离收尾 + S-3 断线与真机 soak;发送历史可删除;历史/文件传输按钮样式对齐;v1.4 主线(S-1~S-5)功能冻结;1186 passed / 6 skipped / 291 subtests。
- v54 (v1.5.0): 正式版 — 终端多会话标签(同窗并发串口/TCP/UDP/虚拟;后台继续收发日志与周期发送;具名互斥 toast;标签状态点/重命名;关键字 Regex/HEX;草稿防抖自动保存;Windows offscreen CI);1329 passed / 11 skipped / 291 subtests。
- v55 (v1.5.1): 正式版 — 搜索惰性分页与全局导航、可逆一键 I/O Graph、示例工程包、Mac 发版门禁与多会话显示选项矩阵;修复 macOS 启动时接收视图未就绪导致的
qFatal/SIGABRT,并使用 Apple Symbols;Modbus CRC/TCP tid 与虚拟注入加固;1359 passed / 11 skipped / 295 subtests。 - v56 (v1.5.2): 正式版 — 绘图扩展(双 Y / XY / 直方图)、仪表盘四控件、Excel/xlsx、PCAP/pcapng 增强、回放驱动真实 TX;切标签自动停多条循环;High/Medium/Low 审计收尾;1433 passed / 11 skipped / 295 subtests。
- v57 (v1.5.3): 正式版 — 主界面下拉防滚轮误触、数据区选区转文本/HEX(弹窗+剪贴板,64 KiB)、会话重命名等主题输入框按钮对齐;阶段 A/B 工程打磨与 CI(契约、静默预算、macOS 烟雾、ruff、覆盖率);1465 passed / 11 skipped / 295 subtests。
- v58 (v1.5.4): 正式版 — 多条循环 per-session、桥接网关 timeout/unit_map、app_style/i18n_ui 薄拆、B6 except 收窄、updater IncompleteRead 修复;Mac DMG 仍由协作者补同一 Release。
- v59 (v1.5.5): 正式版 — 多会话引擎收口:软切标签、后台 RX 喂引擎/AR/触发器;序列/脚本/MBM/录制/宏/DSL per-session;传输/回放仍整窗一份并钉会话;扫描同窗一次;Mac DMG 仍由协作者补同一 Release。
- v60 (v1.5.6): 正式版 — 多会话引擎补齐:传输/回放/扫描/自动应答 per-session;脚本控制台日志、扫描表、录制捕获按标签隔离;脚本 I/O 钉住与超大文件确认等修复;Mac DMG 仍由协作者补同一 Release。
- v61 (v1.5.7): 正式版 — TCP Server 多客户端 PCAP 导出(每对端一条流,广播按发送当时的对端展开,导出前确认);关键字增量高亮 / 搜索节流;Ctrl+Enter 发送;实时日志 flush/fsync;发送背压与清理路径加固。Linux x86_64 官方
.run与 macOS DMG 已挂同一 Release(更新走url_linux/url_mac)。
本项目以 GPL-3.0 开源。
为什么是 GPL:本工具基于 PyQt5,其免费版采用 GPL v3 授权(Riverbank 双授权:GPL 或商业)。 依赖 GPL 库分发,整个应用按 GPL 的传染性须以 GPL-3.0(或兼容协议)发布。其余依赖 pyserial(BSD) / pyqtgraph(MIT) / numpy(BSD) 均为宽松协议,无额外约束。 若将来需要闭源 / 商业分发,可把 PyQt5 换成 PySide6(LGPL)后再改用宽松协议。
Copyright © 2026 heropml. Licensed under the GNU General Public License v3.0.