目录
- [一、为什么要适配 Python IDLE](#一、为什么要适配 Python IDLE)
- [二、先确定适配边界:不能把 Tkinter 窗口直接装进 HAP](#二、先确定适配边界:不能把 Tkinter 窗口直接装进 HAP)
- 三、鸿蒙版本的整体架构
- [四、把 IDLE 的核心工作流在真机上跑通](#四、把 IDLE 的核心工作流在真机上跑通)
-
- 1.编辑器不仅要能输入,还要保持代码上下文
- [2.Run Module 直接进入内嵌 CPython](#2.Run Module 直接进入内嵌 CPython)
- [3.Python Shell 保留交互式命名空间](#3.Python Shell 保留交互式命名空间)
- 4.基础断点调试进入真实暂停状态
- 5.设置需要在应用重启后仍然成立
- 五、适配过程中最棘手的几个问题
-
- [难点一:Tk 事件模型与 ArkUI 状态模型差异很大](#难点一:Tk 事件模型与 ArkUI 状态模型差异很大)
- [难点二:把 CPython 装进 HAP 只是第一步](#难点二:把 CPython 装进 HAP 只是第一步)
- [难点三:执行不能冻结 ArkUI 主线程](#难点三:执行不能冻结 ArkUI 主线程)
- 难点四:语法高亮不能破坏光标和滚动
- 难点五:文件路径必须服从授权与沙箱边界
- 难点六:调试器需要跨线程同步,而不是轮询字符串
- 六、构建、安装与启动
- 七、当前已经覆盖的能力与明确边界
- 八、真机验收口径
- 九、总结
一、为什么要适配 Python IDLE
IDLE 是 CPython 官方发行版长期自带的轻量开发环境。它的价值不在于堆叠复杂工程能力,而在于把代码编辑、解释器执行、交互式 Shell 和入门调试放在一个足够简单的窗口里。对于刚接触 Python 的学习者、需要临时验证标准库行为的开发者,以及只想快速编写一段脚本的用户,IDLE 一直是门槛很低、路径很短的工具。
HarmonyOS PC 要形成完整的开发与生产力生态,除了大型 IDE,也需要这种安装后即可使用的轻量编程工具。适配 IDLE 的意义因此不只是增加一个编辑器,更是验证一条有代表性的技术链路:原本依赖 Tkinter 的桌面应用,怎样进入 Stage 模型;CPython 运行时怎样作为应用的一部分被稳定装入 HAP;ArkTS 界面又怎样与 Native 解释器交换源码、输出、异常和调试状态。
本项目保留 CPython 与 Lib/idlelib/ 上游源码作为行为基准,鸿蒙侧代码集中在 Platforms/HarmonyOS/。当前应用版本为 1.0.0,包名为 com.hongsuite.hongtie,支持 phone、tablet 和 2in1,签名 HAP 同时包含 arm64-v8a 与 x86_64 两套 libidlepc.so。
二、先确定适配边界:不能把 Tkinter 窗口直接装进 HAP
原版 IDLE 的窗口、菜单、文本编辑器、事件循环和大量交互细节都建立在 Tkinter/Tcl/Tk 之上。HarmonyOS PC 的应用入口、窗口生命周期、文件授权和分发方式与传统桌面系统不同,即使先解决 CPython 的交叉编译,也不能让 Tk 窗口自然变成鸿蒙应用。
本次适配采用"保留 Python 语义,重建高频工作流"的方案:界面使用 ArkUI Stage 模型重新实现,Python 代码仍由内嵌 CPython 执行,ArkTS 与 Native 层通过 N-API 通信,标准库则作为 python_stdlib.zip 随 HAP 打包。原版 idlelib 没有被删除,也没有被宣称可以直接运行;它继续承担功能对照和后续补齐行为的基准角色。
| 层次 | 原版 IDLE | 鸿蒙侧实现 |
|---|---|---|
| 应用入口 | Python 进程与 Tk 主循环 | Stage 模型 EntryAbility |
| 桌面界面 | Tkinter/Tcl/Tk | ArkUI 菜单、标签、RichEditor、Shell 与状态栏 |
| Python 执行 | 系统或发行版 CPython | HAP 内嵌 CPython 3.16 运行时 |
| 界面与解释器通信 | Python 对象直接调用 | ArkTS IdleBridge + N-API libidlepc.so |
| 标准库 | 本机 Python 安装目录 | python_stdlib.zip 随包发布并在沙箱中准备 |
| 文件访问 | 任意桌面路径 | DocumentViewPicker 授权 URI 与应用工作区 |
| 调试 | IDLE Debugger 与 Tk 面板 | CPython trace hook + ArkUI 调试面板 |
这个边界有意避免两个误区:鸿蒙版本不是把原版 Tk 窗口换个包名重新打包,也不是只画出编辑器外观的演示程序。编辑、执行、标准输出、异常、交互式 Shell、中断和断点调试都接入了真实 CPython 运行时,只是完整 Stack Viewer、条件断点和 Tk 扩展生态仍保留为后续能力。
三、鸿蒙版本的整体架构
鸿蒙工程由 ArkUI 宿主、ArkTS 服务层、N-API 桥接层和 CPython 运行时四部分组成。EntryAbility.ets 管理应用生命周期与窗口;Index.ets 维护菜单、文件标签、编辑器、Shell 和调试界面;IdleBridge.ets 把界面请求转换为结构化 Native 调用;napi_init.cpp 负责解释器初始化、源码编译执行、输出捕获、中断与调试状态。
text
EntryAbility
└── Index.ets / ArkUI 桌面界面
├── RichEditor、行号、补全与 Code Context
├── 文件标签、查找替换与设置
├── Python Shell 与运行结果
└── Debugger 面板
│
├── FilePickerService / DocumentViewPicker
└── IdleBridge.ets
└── N-API libidlepc.so
├── CPython 3.16
├── 持久 Shell 命名空间
├── stdout / stderr 捕获
├── trace hook、断点与中断
└── python_stdlib.zip
仓库中的主要目录如下:
text
ohos_idle/
├── Lib/idlelib/ # 原版 IDLE 源码与行为基准
├── Include/、Objects/、Python/、Modules/ # CPython 核心与扩展模块
├── InternalDocs/ # 适配设计、矩阵和真机验收记录
└── Platforms/HarmonyOS/
├── __main__.py # doctor/build 命令入口
└── workspace/
├── AppScope/app.json5 # 包名、版本与应用资源
├── build-profile.json5 # SDK、产品和签名配置
└── entry/src/main/
├── ets/entryability/ # Stage 模型入口
├── ets/pages/Index.ets # 主界面与交互状态
├── ets/services/ # 文件选择与运行时桥接
├── cpp/napi_init.cpp # N-API 与 CPython 运行时
└── resources/rawfile/ # Python 标准库压缩包
四、把 IDLE 的核心工作流在真机上跑通
以下五张图片均来自仓库当前签名 HAP 在 HarmonyOS PC 真机上的实际运行画面。测试设备为 HUAWEI MateBook Pro(HAD-W32,2in1),系统版本为 OpenHarmony-6.1.0.115,物理分辨率为 3120×2080。验证时重新安装并启动 entry-default-signed.hap,随后在应用内完成编辑、运行、Shell 执行、断点调试和设置面板操作。
1.编辑器不仅要能输入,还要保持代码上下文
应用启动后,中间区域显示带行号的 Python 编辑器,顶部保留经典 IDLE 风格的菜单与多文件标签,底部则是 Python Shell。截图中的源码同时包含内置函数、字符串、关键字、注释和数字,可以看到这些 token 已按类别分色;输入 print 时,Completion 面板给出内置名称候选。

编辑器使用单层 RichEditor 承载文本、光标和样式,行号区根据可见源码同步更新。这样处理是为了避免早期"透明输入层 + 高亮显示层"方案中出现的字符宽度、滚动位置和光标偏移。补全候选综合运行时名称、本地标识符和工作区文件名生成;输入调用表达式时还可以显示 Call Tip。它不是完整语言服务器,但已经覆盖学习和脚本编写中最常见的输入反馈。
2.Run Module 直接进入内嵌 CPython
在 Run 菜单执行 Run Module 后,当前文档会先同步到应用工作区,再由 Native 层编译和执行。截图中的 Shell 明确显示运行文件路径,随后输出 Hello from HarmonyOS PC、sys.argv 和数值 123,状态栏回到 run completed。

运行过程并不是 ArkTS 对源码做字符串模拟。libidlepc.so 以 CPython C API 编译代码对象,在独立工作线程中执行,并接管 stdout、stderr 和异常格式化。普通输出与 traceback 使用同一份结构化结果返回页面,因此语法错误、运行时错误和正常结束可以落到一致的状态流中。标准库压缩包随 HAP 提供,运行时通过隔离配置建立模块搜索路径,避免依赖设备上另行安装 Python。
3.Python Shell 保留交互式命名空间
为排除前一轮运行输出的干扰,先执行 Restart Shell,再输入 sum(range(101))。真机返回结果 5050,提示符随后重新出现;截图顶部同时给出 Python 3.16 interactive shell restarted,可以直接区分本轮交互与之前的模块运行记录。
Native 层为 Shell 单独维护持久的 globals 字典,连续输入的变量和导入不会在每条命令后丢失。提交前通过 codeop.compile_command 判断源码是完整、未完成还
是语法错误,多行 for、if、函数定义等代码块可以继续留在输入区,完成后再统一执行。页面同时维护上下历史、Restart Shell 和异步 Interrupt Execution,使 Shell 更接近开发工具,而不是一次性表达式计算器。
4.基础断点调试进入真实暂停状态
启用 Debugger 后再次运行当前模块,程序在 main.py:1 进入暂停状态。调试面板提供 Continue、Step、Over、Out 和 Stop,左右两侧分别显示 Locals 与 Globals;编辑器行号中的星号则表示已经持久化的普通断点。

调试功能由 CPython trace hook 驱动。Native 层记录当前文件、行号、调用深度和断点集合,在 trace line 事件中决定是否暂停;ArkUI 以短周期读取结构化快照,并将暂停位置、函数名和变量映射到界面。Continue、Step、Over、Out 和 Stop 会改变 Native 调试命令与运行模式,再唤醒等待中的解释器线程。当前实现已经能完成首行暂停、普通断点和基础单步,但还不能切换完整的多层调用栈,也没有条件断点和异常自动暂停。
5.设置需要在应用重启后仍然成立
Options 菜单中的 Configure IDLE 面板可以调整编辑器字号、缩进宽度、Tab/空格、Shell 高度,以及行号、Shell 和 Code Context 的显示状态。截图中的配置来自真机当前状态,并与调试器、补全和 Shell 面板保持在同一窗口布局中。

这些选项通过 HarmonyOS Preferences 保存,而不是只修改当前页面的临时变量。断点也按工作区文件分别持久化,因此切换标签或重启应用后仍能恢复到对应文件。对桌面开发工具而言,会话恢复并非装饰功能:编辑字号、面板高度和调试断点如果每次启动都归零,连续使用的成本会明显高于原版 IDLE。
五、适配过程中最棘手的几个问题
难点一:Tk 事件模型与 ArkUI 状态模型差异很大
原版 IDLE 可以直接操作 Tk 文本控件的 tag、mark、selection 和事件绑定,菜单行为也围绕 Tk 窗口组织。ArkUI 更强调声明式状态与组件重建,不能把原有控件调用逐条翻译。适配时需要先把"当前文件、文本、光标、选择区、搜索结果、Shell 状态和调试状态"整理成稳定的数据模型,再由界面根据状态渲染。否则同一份文本很容易在编辑器、行号、高亮和文件标签之间产生不同步。
难点二:把 CPython 装进 HAP 只是第一步
解释器库能够链接,并不代表 import、编码和标准库马上可用。运行时需要正确设置 program name、模块搜索路径、工作目录和隔离选项,还要让 python_stdlib.zip 在应用沙箱中可访问。本项目使用 PyConfig_InitIsolatedConfig 初始化解释器,并由应用在首次启动时准备标准库资源,避免误读开发机路径。HAP 中同时打包两种 CPU 架构,Native 侧再按目标 ABI 选择对应的 libpython3.16.a。
难点三:执行不能冻结 ArkUI 主线程
用户运行脚本时可能遇到长循环、阻塞调用或需要调试暂停的程序。如果直接从界面线程调用解释器,窗口会失去响应,Interrupt 和 Stop 也无处执行。当前实现把运行请求放进 N-API 异步工作队列,Native 层管理 GIL 和运行状态,界面只接收结果与周期性调试快照。中断通过原子标记和 trace hook 转换为 KeyboardInterrupt,在脚本停止后再恢复到可继续操作的 Ready 状态。
难点四:语法高亮不能破坏光标和滚动
代码高亮最初看起来只是给关键字换颜色,但在编辑器中还涉及文本替换、光标恢复、选择范围、输入法合成和长文档滚动。若每次输入都重建多个叠加层,光标和视觉文本很快会错位。鸿蒙版本将文本与样式统一交给 RichEditorStyledStringController,在受控时机重算 span,并显式恢复 selection;行号则根据滚动位置显示当前可见范围。这个方案牺牲了一部分复杂编辑器扩展能力,但显著提高了真机输入稳定性。
难点五:文件路径必须服从授权与沙箱边界
传统 IDLE 默认可以从任意桌面路径打开和保存文件,鸿蒙应用则需要通过系统选择器获得 URI。FilePickerService 使用 DocumentViewPicker 完成 Open、Save As 和 Save Copy As,Native 层负责读取、写入及错误结构化。外部 URI、应用工作区路径和显示名称不能混为一个字段,否则保存副本、标签切换和断点归属都会出现歧义。适配中将文件标识、显示名称、实际 URI 和文本状态分开维护,才让多文件工作流稳定下来。
难点六:调试器需要跨线程同步,而不是轮询字符串
解释器暂停时必须等待用户命令,但 ArkUI 仍要持续响应。Native 层用互斥量与条件变量保护调试快照和命令,trace hook 只在满足首行、单步、断点、Over 或 Out 条件时进入等待;页面侧读取 JSON 快照并更新当前行与变量表。变量展示还需要安全地取得对象表示,避免一个异常的 repr 破坏整个调试响应。当前基础链路已经稳定,但完整多栈帧浏览仍需要更细的帧生命周期管理,因此没有提前标成已完成。
六、构建、安装与启动
工程当前使用 HarmonyOS SDK 5.0.0(12),构建前可以在仓库根目录运行环境检查:
bash
python3 Platforms/HarmonyOS doctor
检查通过后执行:
bash
python3 Platforms/HarmonyOS build
该入口会在 Platforms/HarmonyOS/workspace/ 中安装 ohpm 依赖并调用 Hvigor。签名 HAP 的默认位置为:
text
Platforms/HarmonyOS/workspace/entry/build/default/outputs/default/entry-default-signed.hap
也可以使用 DevEco Studio 打开 Platforms/HarmonyOS/workspace/,确认 SDK 组件与设备签名后直接运行。如果命令行出现 SDK component missing,应先在 SDK Manager 中补齐或修复与 5.0.0(12) 对应的 SDK 组件;doctor 能确认工具与工程文件存在,但不能替代 Hvigor 对 SDK 完整性的校验。
安装与启动示例如下:
bash
HDC=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc
"$HDC" list targets
"$HDC" install -r \
Platforms/HarmonyOS/workspace/entry/build/default/outputs/default/entry-default-signed.hap
"$HDC" shell aa force-stop com.hongsuite.hongtie
"$HDC" shell aa start -b com.hongsuite.hongtie -a EntryAbility
本次截图验证中,仓库当前约 19 MB 的签名 HAP 已在设备 3QC0124C20001268 上完成覆盖安装并成功启动。包内可以确认 libs/arm64-v8a/libidlepc.so、libs/x86_64/libidlepc.so 与约 5.4 MB 的 resources/rawfile/python_stdlib.zip 均已实际打包。
七、当前已经覆盖的能力与明确边界
当前版本已经形成了从源码到运行结果的主要闭环:
- 多文件标签、新建、打开、保存、另存为、保存副本和标签切换;
RichEditor代码编辑、行号、Python 语法颜色、缩进、注释和 Code Context;- Undo/Redo、剪切复制粘贴、查找替换、项目内查找和跳转行;
- 补全候选、Call Tip、Module Browser 与 Python Path Browser;
- Run Module、Run Customized、Check Module、stdout、stderr 和 traceback;
- 持久 Python Shell、多行输入、上下历史、Restart Shell 和中断执行;
- 普通断点、Continue、Step、Over、Out、Stop 与当前帧 Locals/Globals;
- 编辑器偏好、Shell 布局与按文件断点持久化;
- arm64-v8a/x86_64 Native 库和 Python 标准库随 HAP 分发。
仍需明确保留的边界包括:
- 完整的多栈帧 Stack Viewer 与帧切换;
- 条件断点、异常事件自动暂停和更完整的调试器行为;
- 原版 IDLE 的主题编辑器、完整快捷键配置和多顶层窗口模型;
- 自动括号闪烁、打印窗口、完整最近文件与编码/外部修改确认流程;
- Tkinter 窗口及原版 IDLE 扩展生态的直接兼容。
因此,当前版本更准确的定位是"Python IDLE HarmonyOS PC 可用迁移版"。学习 Python、编写脚本、运行模块、使用交互式 Shell 和进行基础断点调试已经可以连续完成;依赖完整 Tk 扩展、多窗口或高级调试能力的工作流,仍应按未适配处理。
八、真机验收口径
本文截图对应的五条链路均在同一次真机运行过程中完成:应用进入原生窗口后显示工作区;Run Module 输出源码中的三组结果;Shell 执行 sum(range(101)) 返回 5050;Debugger 在 main.py:1 真实暂停并开放控制按钮;Configure IDLE 展示当前持久化设置。
除截图所示功能外,仓库的验收记录还覆盖了文件选择器打开与保存、多标签关闭、Undo/Redo、剪贴板、查找替换、格式化、补全、Call Tip、Module Browser、Path Browser、前后台恢复、进程重启恢复和断点持久化。验收结论只使用"真机完成"和"未适配"两类口径,不把菜单存在或源码中已有方法等同于用户已经可用。
本次设备侧可直接确认的信息如下:
| 项目 | 结果 |
|---|---|
| 设备 | HUAWEI MateBook Pro(HAD-W32,2in1) |
| 系统 | OpenHarmony-6.1.0.115 |
| 设备 ABI | arm64-v8a |
| HAP 覆盖安装 | 成功 |
| EntryAbility 启动 | 成功 |
| 内嵌运行时 | Python 3.16.0a0,Clang 17,on harmonyos |
| Run Module | 成功输出并回到 run completed |
| Python Shell | 成功返回 5050 并回到 shell completed |
| 基础调试 | 成功暂停于 main.py:1 |
九、总结
Python IDLE 的鸿蒙 PC 适配真正困难的部分,不是复刻灰色菜单栏,而是让编辑器、文件授权、CPython 生命周期、标准库路径、异步执行、中断和调试暂停在同一个应用里稳定协作。任何一层只做到"能编译",都不足以形成用户可以连续使用的开发体验。
本项目用 ArkUI 接住 HarmonyOS 的窗口与生命周期,以 N-API 建立清晰的运行时边界,再把 CPython 和标准库作为应用资产交付。五张真机截图覆盖了编辑、运行、交互、调试和设置这条核心路径,说明应用已经越过单纯界面展示阶段,具备轻量 Python 开发工具的实际使用价值。
对类似工具的迁移,这次实践给出的顺序也比较清晰:先确定不能直接复用的桌面依赖,再保住最关键的用户闭环;随后把解释器或核心引擎收敛到稳定的 Native 边界,最后用真机上的真实输入、真实输出、文件 URI、停止行为和重启恢复验证结果。做到这些,适配才不只是"应用能够打开",而是用户确实能够完成工作。