分析日期:2026-06-23
项目路径:/home/zbc/pangu/GeneralAndroid/main/hideapi/tool_new/
一、代码规模总览
| 指标 | 数值 |
|---|
| Python 文件总数 | ~35 个核心文件 |
| 总代码行数 | ~25,300 行 |
最大单文件 gui_manager.py | 6,339 行(上帝类) |
第二大文件 trace_page.py | 4,495 行 |
样式文件 styles/ | 14 个文件,约 3,000 行 |
| 自定义控件类 | 约 20 个 |
| QThread 子类 | 8 个 |
| Mixin 页面类 | 6 个 |
二、PyQt6 特性使用清单
基础控件(大量使用)
- 布局:QVBoxLayout, QHBoxLayout, QGridLayout, QStackedWidget, QSplitter
- 标准控件:QPushButton, QLabel, QLineEdit, QComboBox, QTextEdit, QCheckBox, QGroupBox, QScrollArea, QTabWidget, QListWidget, QTableWidget, QTreeWidget, QProgressBar, QSpinBox
- 对话框:QDialog, QFileDialog, QMessageBox, QInputDialog, QMenu
中级特性(中等使用)
| 特性 | 使用量 | 说明 |
|---|
| pyqtSignal | 20+ 个自定义信号 | 8 个 QThread 子类中定义,是核心通信机制 |
| QSS 样式表 | 14 个文件 | 基于集中色板 _colors.py,使用 setProperty("class", ...) 语义化样式 |
| 拖拽支持 | 3 处 | APK 安装、目录选择、Trace 文件输入 |
| eventFilter | 1 处 | 图片预览窗口的鼠标拖拽平移 |
| QTimer | 5+ 处 | 设备轮询(1500ms)、录屏计时、AI聊天节流、延迟刷新 |
高级特性(少量使用)
| 特性 | 文件 | 说明 |
|---|
| QPainter 自定义绘制 | video_trimmer.py | SpinnerOverlay(旋转动画)、RangeSlider(双端滑块)、CrossfadeLabel(交叉淡入) |
| QPropertyAnimation | ai_chat_widgets.py | ”思考中” 脉冲点动画 |
| QSocketNotifier + PTY | gui_manager.py | 内嵌 Linux 终端(仅 Linux) |
| ANSI 转义码解析 | gui_manager.py | TerminalTextEdit 手动解析颜色代码 |
| QTextDocument.find | gui_manager.py | 日志搜索高亮(支持正则) |
三、自定义控件清单
| 控件 | 文件 | 复杂度 | 迁移难度 |
|---|
TerminalTextEdit | gui_manager.py | 高 — PTY 交互 + ANSI 解析 | ★★★★★ |
RangeSlider | video_trimmer.py | 高 — 双端拖拽 + QPainter | ★★★★★ |
ImagePreviewDialog | gui_manager.py | 高 — 缩放/拖拽/播放/交叉淡入 | ★★★★☆ |
SpinnerOverlay | video_trimmer.py | 中 — QPainter 旋转弧线 | ★★★★☆ |
CrossfadeLabel | video_trimmer.py | 中 — QPainter 双图混合 | ★★★★☆ |
VideoTrimDialog | video_trimmer.py | 高 — 完整视频裁剪 UI | ★★★★☆ |
MultiImagePreviewDialog | gui_manager.py | 中 — 网格对比 + 同步缩放 | ★★★☆☆ |
VideoFrameViewer | video_trimmer.py | 中 — 帧序列浏览器 | ★★★☆☆ |
AssistantBubble | ai_chat_widgets.py | 中 — 流式渲染 + Markdown | ★★★☆☆ |
ThinkingIndicator | ai_chat_widgets.py | 中 — 脉冲动画 | ★★★☆☆ |
_DropLineEdit / _DropComboBox | trace_page.py | 中 — 拖拽 + 右键菜单 | ★★★☆☆ |
ToolCallWidget | ai_chat_widgets.py | 低 — 状态卡片 | ★★☆☆☆ |
_ChatInputEdit | ai_chat_page.py | 低 — Enter 提交 | ★☆☆☆☆ |
四、线程/异步模型
| 模式 | 使用位置 | 数量 |
|---|
QThread + pyqtSignal | AdbWorker, TraceWorker, V2PWorker, ClaudeStreamWorker, UpdateWorker 等 | 8 个子类 |
QTimer | 设备轮询、录屏计时、AI节流渲染、自动更新 | 5+ 处 |
QSocketNotifier | PTY 终端输出监听 | 1 处 |
subprocess.Popen (QThread 内) | AdbWorker 逐行读取 stdout | 核心流程 |
threading.Thread | trace_page.py | 极少 |
关键点:
- 没有使用
asyncio
- 没有使用
QRunnable / QThreadPool
- 整个异步模型完全基于 QThread + pyqtSignal
- 信号/槽是贯穿全应用的核心通信机制
五、架构耦合度分析
好的解耦设计
functions/ 下业务模块是纯数据模块,返回 (button_text, command, tooltip) 三元组,不依赖 UI
COMMAND_REGISTRY 提供函数名到命令生成器的纯映射
AdbController 是纯工具类(subprocess 封装)
- 样式完全分离在
styles/ 目录,通过 apply_xxx_style(widget) 注入
耦合较紧的部分
gui_manager.py 上帝类(6,339 行):UI 构建 + 命令调度 + 设备管理 + 文件操作 + HTTP 服务器 + PTY 终端 + 日志搜索 + 录屏管理
- 6 个 Mixin 混入
AndroidToolWindow,通过 self 直接访问主窗口所有属性
- 命令执行流
prepare_and_run() → run_background() → AdbWorker(QThread) → result_signal 与 QThread 深度绑定
六、平台特定代码
| 功能 | 文件 | 平台限制 |
|---|
| PTY 内嵌终端 | gui_manager.py | 仅 Linux(pty.openpty + QSocketNotifier) |
| 桌面快捷方式 | gui_manager.py | 仅 Linux(.desktop 文件) |
| libxcb-cursor.so | main_gui.py | 仅 Linux(X11 cursor) |
| 跨平台二进制 | platform_bin.py | 已做好三平台适配 ✅ |
| 构建脚本 | build_ci.py | 已区分三平台 ✅ |
七、迁移工作量估算
按目标框架
| 目标框架 | 预计时间 | 代码重写比例 | 说明 |
|---|
| PySide6 | 1-2 天 | ~5% | API 99% 兼容,仅 import 和信号语法微调 |
| 另一个 Python GUI | 3-5 周 | ~65% | 需重写所有 UI 和线程模型 |
| Electron + React | 6-10 周 | ~80% | 需全部重写为 JS/TS,仅命令逻辑可参考 |
| Tauri + Vue | 6-10 周 | ~80% | 同上,额外需学 Rust |
| Flutter | 8-12 周 | ~85% | 完全不同的语言和框架 |
可直接复用的部分
functions/ 目录下约 4,000 行业务逻辑(命令定义、按钮配置、注册表)
config.py / config_paths.py / device_info.py(纯数据配置)
platform_bin.py(跨平台路径解析)
- 如果迁移到 Web 方案,以上逻辑需要移植但思路可完全复用
需要完全重写的部分
- QSS 主题系统(14 文件)→ 目标框架样式系统
- QThread 异步模型(8 个子类)→ 目标框架线程/异步模型
- QPainter 自定义绘制(3 个控件)→ Canvas/SVG/自绘 API
- gui_manager.py 上帝类 → 需先重构再迁移
八、建议
- 如果不切换框架:优先将 PyQt6 → PySide6(解决许可问题,工作量极小)
- 如果决定迁移:先重构
gui_manager.py 上帝类(拆分为独立页面模块),再开始迁移
- 无论如何:
functions/ 目录的纯数据架构是正确的设计,应该在新框架中保持这种解耦