Windows 下 Qt for WebAssembly 实战:从环境搭建到浏览器运行
1. 为什么要在 Windows 上折腾 Qt for WebAssembly1.1 这个组合到底解决什么问题先把概念理清楚。Qt for WebAssembly 是 Qt 官方提供的一个平台移植目标它把 Qt 应用编译成 WebAssembly 字节码最终产物是一个.wasm文件加上配套的.js胶水代码和.html宿主页面。浏览器加载这套东西之后就能直接跑一个原本用 C / Qt 写的桌面级应用不需要用户安装任何东西打开网页就能用。那为什么强调“in Windows”因为绝大多数 Qt 桌面开发者日常主力环境就是 Windows Qt Creator MSVC 或者 MinGW。大家手里已经有一堆现成的 Qt 项目想快速验证“能不能搬到浏览器里跑”最自然的路径就是在自己熟悉的 Windows 机器上直接搞而不是先装个 Linux 虚拟机或者折腾双系统。这个标题的核心诉求就是在 Windows 环境下把 Qt 项目编译成 WebAssembly并在浏览器里跑起来。它适合谁三类人最需要手里有 Qt 桌面项目想低成本做一个 Web 演示版或者在线试用版的开发者做工业软件、仪器控制面板、数据可视化工具希望客户免安装就能看效果的产品团队想学习 WebAssembly 实际工程落地但不想从零写 C 胶水代码的技术爱好者。1.2 和传统方案比它的优势和代价传统上要把 Qt 程序搬到 Web 上路子无非几条用 Qt WebGL 做流式渲染需要服务器持续推流、重写成 JavaScript工作量巨大、或者用云桌面方案体验差、成本高。Qt for WebAssembly 的思路完全不同它是把编译产物直接丢给浏览器执行服务端只负责发静态文件压力极小。但代价也很明显我先把丑话说在前面对比维度Qt for WebAssembly传统桌面 Qt云桌面/流式方案部署方式静态文件托管本地安装包服务端推流客户端要求支持 Wasm 的现代浏览器对应操作系统客户端软件性能约为原生 30%~70%原生取决于网络包体积较大几十 MB 起中等极小文件系统虚拟内存 FS刷新即丢真实磁盘服务端磁盘多线程需要特殊配置原生支持原生支持这张表是我自己踩过之后总结的尤其是包体积和文件系统这两条后面会展开讲。理解了这个前提你才知道哪些项目适合搬、哪些不适合。1.3 整体思路先捋一遍在 Windows 上做这件事完整链路是这样的安装 Emscripten 工具链它提供emcc、em等编译器把 C 编译成 Wasm→ 用 Emscripten 编译一份 Qt 的 Wasm 版本官方有预编译包也可以自己编→ 在 Qt Creator 里配置一个 Wasm Kit → 用这个 Kit 编译你的项目 → 用本地 HTTP 服务器托管产物 → 浏览器打开验证。关键点在于Qt 本身必须先被编译成 Wasm 版本你的项目才能链接它。这一步是很多人卡住的地方因为官方预编译包和你的 Qt 版本、Emscripten 版本必须严格对应版本错配会报一堆莫名其妙的链接错误。下面我按顺序拆开讲。2. 环境搭建工具链选型与版本对齐2.1 Emscripten 的安装与版本锁定Emscripten 是整个链路的地基。Windows 上安装它最省事的方式是用官方提供的emsdk。我建议把它放在一个路径不含空格和中文的目录比如D:\emsdk因为后面 Qt 的构建脚本对路径比较敏感带空格的路径偶尔会出问题。安装步骤大致是拉取 emsdk 仓库 → 执行emsdk install指定版本 → 执行emsdk activate激活 → 运行环境变量脚本。这里最关键的是版本选择。Qt 每个小版本对 Emscripten 的版本都有明确要求比如某个 Qt 6.x 版本要求 Emscripten 3.1.x 系列。你如果随手装了最新版很可能编译 Qt 时直接失败。# 进入 emsdk 目录后 emsdk install 3.1.37 emsdk activate 3.1.37 emsdk_env.batemsdk_env.bat这一步是设置当前命令行会话的环境变量每次开新终端都要跑一次或者你可以把它写进系统环境变量里一劳永逸。我个人的习惯是写一个setenv.bat里面先调emsdk_env.bat再设置 Qt 相关的路径双击就能进到准备好的环境。注意不要同时激活多个 Emscripten 版本emsdk的激活是全局覆盖式的切换版本后最好重开终端否则emcc -v显示的版本可能和你以为的不一致。2.2 Qt for WebAssembly 的获取方式拿到 Qt 的 Wasm 版本有两条路。第一条是用 Qt 官方在线安装器在组件列表里勾选对应版本的 WebAssembly 组件它会直接下载预编译好的 Qt 库。这条路最省心适合绝大多数人。第二条是自己用源码编译适合需要裁剪模块、或者官方没提供对应版本的情况但编译一次动辄一两个小时非必要不推荐。用在线安装器时要注意WebAssembly 组件是挂在某个具体 Qt 版本下面的比如Qt 6.5.3 WebAssembly。装完之后你的 Qt 安装目录下会多出一个类似6.5.3/wasm_32的文件夹里面是头文件、库和qmake。这个路径后面配置 Kit 时要用到。版本对齐的黄金法则是Qt 版本、Emscripten 版本、Qt Creator 版本三者要匹配。Qt Creator 从某个版本开始才内置了对 Wasm Kit 的良好支持太老的 Creator 识别不了。我一般用和 Qt 同期的 Creator 版本省得折腾。2.3 Qt Creator 里的 Kit 配置细节打开 Qt Creator进到“工具 选项 设备 WebAssembly”这里要填 Emscripten 的路径。填完之后Creator 通常会自动检测出一个 WebAssembly Kit。如果没有就手动到“构建套件”里新建一个编译器选 Emscripten 的emQt 版本选你刚装的 Wasm 版 Qt。这里有个容易忽略的点Qt Creator 的 Wasm Kit 默认可能不带调试器因为 Wasm 的调试链路和原生不一样。如果你需要断点调试得额外配置浏览器调试或者用emrun配合。日常开发我更多是靠console.log和 Qt 的qDebug输出到浏览器控制台效率其实不低。配置完成后建议先拿 Qt 自带的示例项目试编译一次比如那个经典的analogclock或者calculator。能编译通过、能在浏览器打开说明工具链没问题再上自己的项目。3. 核心细节编译配置与产物结构3.1 .pro 或 CMakeLists 里的关键改动Qt for WebAssembly 的编译配置和桌面版有差异主要集中在链接选项和资源处理上。如果你用的是 qmake 的.pro文件通常需要针对 Wasm 平台做条件判断wasm { QMAKE_LFLAGS -s ALLOW_MEMORY_GROWTH1 QMAKE_LFLAGS -s EXPORTED_RUNTIME_METHODS[ccall,cwrap] QMAKE_LFLAGS --preload-file assets }ALLOW_MEMORY_GROWTH这个选项非常关键。Wasm 的线性内存默认是固定大小的如果你的应用运行中需要分配超过初始值的内存不加这个就会直接崩。加上它之后内存可以动态增长代价是略微损失一点性能但稳定性提升明显。--preload-file是把资源目录打包进虚拟文件系统。Qt 应用经常要读图片、字体、配置文件这些在浏览器里没有真实磁盘必须通过预加载打包。打包后产物里会多一个.data文件浏览器加载时一并拉取。如果你用 CMake写法类似通过target_link_options添加这些标志。CMake 的好处是可以更精细地控制不同 target 的选项大型项目里更清晰。3.2 产物文件到底都是什么编译成功后构建目录里会出现几个文件很多人第一次看到会懵文件作用是否必须app.html宿主页面负责加载和启动是app.jsEmscripten 生成的胶水代码是app.wasm实际的编译产物是app.data预加载的资源包有资源时才有qtloader.jsQt 提供的加载器是qtloader.js是 Qt 封装的一层它负责处理加载进度、错误提示、以及把 Qt 的运行时和 Emscripten 的运行时对接起来。默认生成的app.html会引用它。你可以改app.html的样式比如加个加载动画、改背景色但不要动qtloader.js的核心逻辑除非你很清楚自己在干什么。提示默认的app.html里 canvas 尺寸是写死的如果你的应用要自适应窗口需要改 HTML 和 CSS让 canvas 跟随容器大小同时监听 resize 事件通知 Qt 重新布局。3.3 资源打包的取舍前面提到--preload-file这里展开说下取舍。预加载的资源会全部塞进.data文件浏览器启动时一次性下载。好处是运行时读取快坏处是首屏加载体积大。如果你的资源有几十 MB用户打开页面要等很久。我的经验是分两类处理启动必需的资源比如主界面图标、默认字体用预加载按需加载的大资源比如用户点开某个功能才用的数据文件走运行时下载通过 Emscripten 的FSAPI 或者fetch拿到后写入虚拟文件系统。这样首屏能快不少。另外Qt 的字体处理在 Wasm 下有个坑系统字体是没有的所有字体都得自己打包。如果你用了某个特定字体记得把它加进资源列表否则界面上文字可能显示成方块或者默认字体。4. 实操过程从编译到浏览器跑起来4.1 完整编译流程走一遍假设你已经配好了 Kit项目也准备好了完整流程是这样的在 Qt Creator 里切换到 WebAssembly Kit执行“构建”。第一次构建会比较慢因为要处理所有依赖。构建完成后到构建目录里找到app.html。因为浏览器对file://协议加载 Wasm 有安全限制不能直接双击 html 打开必须用 HTTP 服务器托管。起一个本地服务器比如用 Python 自带的python -m http.server 8000在构建目录下执行。浏览器访问http://localhost:8000/app.html。第 3 步是新手最容易踩的坑直接双击打开会看到一堆跨域或者 MIME 类型错误然后以为编译失败了。其实产物没问题只是加载方式不对。Qt Creator 其实内置了一个“运行”功能它会自动起一个服务器并打开浏览器用这个更省事。但理解背后的原理还是有必要的尤其是你要部署到真实服务器时。4.2 部署到真实服务器的注意事项本地跑通之后下一步就是部署。Wasm 文件对服务器的 MIME 类型有要求.wasm必须以application/wasm返回否则浏览器会拒绝流式编译退化成慢速编译甚至报错。主流服务器Nginx、Apache较新版本都内置了这个映射但老版本可能需要手动加。Nginx 里加一行types { application/wasm wasm; }另外.data文件和.wasm文件通常比较大建议服务器开启 gzip 或 brotli 压缩。Wasm 的压缩率相当可观我实测过一个 30MB 的 wasm 压到 8MB 左右首屏加载时间能砍掉一大半。不过要注意压缩和流式编译有冲突某些配置下需要权衡。还有一个细节缓存策略。Wasm 产物更新后文件名不变的话浏览器可能用旧缓存。建议在构建时给文件名加哈希或者配置服务器对.wasm、.js用较短的缓存时间。4.3 一个最小可运行示例的完整记录我拿一个最简单的 Qt Widgets 程序做演示就一个窗口加一个按钮点击后弹个消息框。这个例子足够小能快速验证整条链路。.pro文件内容QT widgets SOURCES main.cpp wasm { QMAKE_LFLAGS -s ALLOW_MEMORY_GROWTH1 }main.cpp就是标准的 Qt 入口创建QApplication、一个QPushButton连接clicked信号到QMessageBox::information。没有任何特殊处理。编译过程大概两三分钟产物目录里出现了app.html、app.js、app.wasm。起服务器、打开浏览器看到按钮渲染出来点击弹出消息框说明整条链路通了。这个过程虽然简单但它验证了工具链、Kit 配置、资源加载、运行时全部正常是后续复杂项目的基础。注意第一次加载会比较慢因为浏览器要下载并编译 wasm。控制台里能看到加载进度。如果卡在某个百分比不动多半是资源路径或者 MIME 类型的问题。5. 常见问题与排查技巧实录5.1 编译期报错速查编译阶段的问题八成出在版本和路径上。我整理了一张速查表报错现象可能原因解决方向找不到emscripten.hEmscripten 环境未激活重跑emsdk_env.bat链接时符号未定义Qt 版本与 Emscripten 不匹配核对官方版本对应表qmake找不到Kit 里 Qt 路径配错重新指定 wasm_32 目录资源打包失败路径含空格或中文换纯英文无空格路径内存不足报错未开内存增长加ALLOW_MEMORY_GROWTH版本对应关系我强烈建议去查 Qt 官方文档里的那张表不要凭感觉。我见过太多人因为 Emscripten 版本高了一两个小版本编译 Qt 时卡在某个模块上排查半天才发现是版本问题。5.2 运行期问题排查运行期的问题更隐蔽因为浏览器控制台的报错有时候不够直观。几个典型场景白屏什么都不显示。先看控制台有没有报错。如果没有明显报错可能是 canvas 尺寸为 0或者 Qt 的事件循环没启动。检查app.html里 canvas 的样式确保它有实际宽高。界面显示但交互无响应。多半是事件没绑定上或者焦点问题。Wasm 下键盘事件需要 canvas 获得焦点有时候要手动focus()一下。中文显示成方块。字体没打包。把中文字体加进资源并在代码里设置应用字体。刷新后数据丢失。这是预期行为Wasm 的文件系统是内存态的刷新页面等于重启应用。需要持久化的数据得走localStorage或者 IndexedDB通过 JS 交互存取。5.3 性能优化的几个实操点Wasm 的性能优化我总结下来最有效的几招第一开启编译优化。构建时用 Release 模式Emscripten 的-O2或-O3能显著提升运行速度代价是编译时间变长。开发阶段可以用-O0加快迭代发布时切到高优化。第二减少不必要的模块。Qt 有很多模块你的项目用不到的就别链接。比如纯 Widgets 应用不需要 QtQuick纯计算不需要 QtNetwork。链接的模块越少wasm 体积越小加载越快。第三控制内存增长策略。ALLOW_MEMORY_GROWTH虽然方便但每次增长都有开销。如果你的应用内存需求可预测可以设置一个合理的初始值减少增长次数。第四资源懒加载。前面提过的按需加载对首屏体验提升很大。5.4 我踩过的几个印象深刻的坑说几个文档里不太会写、但实际会遇到的坑。一个是路径大小写问题。Windows 文件系统不区分大小写但 Emscripten 打包资源时是区分的。你在代码里写images/Logo.png实际文件叫logo.pngWindows 上编译没问题但打包进虚拟文件系统后运行时找不到。这个坑很隐蔽因为编译期不报错。另一个是多线程。Qt 的某些功能默认会起线程但 Wasm 的多线程需要特殊配置SharedArrayBuffer、COOP/COEP 响应头配置不当会直接崩。如果你的应用不是必须多线程建议先单线程跑通再考虑开多线程。还有一个是时间函数。Wasm 里的时间获取和原生略有差异某些依赖高精度计时的逻辑可能会有偏差。做性能测试时要留意这一点。6. 适用边界与后续扩展方向6.1 什么样的项目适合搬不是所有 Qt 项目都适合搬到 Wasm。我的判断标准是界面交互为主、计算量适中、不依赖本地硬件和真实文件系统的项目最适合。比如数据看板、配置工具、教学演示、轻量级编辑器这些搬过去体验都不错。反过来依赖大量本地文件读写、需要调用系统 API、对性能极度敏感比如实时音视频处理的项目搬过去会很痛苦。Wasm 的沙箱环境决定了它和真实系统之间有一道墙跨这道墙的成本有时候比重新写还高。6.2 和 JS 交互的扩展玩法Qt for WebAssembly 提供了一套和 JavaScript 互调的机制通过EM_ASM、emscripten_run_script这些接口C 可以调 JSJS 也可以调 C 导出的函数。这个能力打开了很大的想象空间。比如你可以让 Qt 界面负责复杂的业务逻辑和渲染把和浏览器 API 相关的部分比如调用摄像头、读写 localStorage、发网络请求交给 JS 处理两边通过回调通信。这样既复用了现有的 Qt 代码又能利用浏览器的原生能力。我做过一个实验Qt 端负责界面和数据处理JS 端负责把结果通过浏览器的下载 API 保存成文件。整个流程跑下来很顺畅用户感觉就是一个普通的网页应用。6.3 打包体积的持续优化体积是 Wasm 应用绕不开的话题。一个空白的 Qt Widgets 应用编译出来wasm 加 js 加 data 可能就有十几 MB。加上业务代码和资源很容易到几十 MB。对于网络条件一般的用户这个体积是劝退级别的。优化方向有几个用-Os优化体积而非速度、裁剪 Qt 模块、用wasm-opt做二次优化、资源压缩。wasm-opt是 Binaryen 工具链里的工具能对 wasm 做死代码消除和压缩效果有时候能到 20% 以上。不过它和 Emscripten 的版本也有对应关系用之前确认一下。我在实际项目里的体会是体积优化是个持续的过程不要指望一次搞定。先保证功能跑通再逐步瘦身每次优化后测一下加载时间找到性价比最高的那个平衡点。对于内部工具或者局域网环境体积没那么敏感对于面向公网的产品体积就是生命线值得花大力气。最后分享一个小技巧如果你只是想快速给客户看个效果不追求完美可以用 Qt Creator 的“运行”直接生成一个临时服务器链接配合内网穿透工具这里指合法的内网映射服务给客户访问省去正式部署的麻烦。但正式上线前还是老老实实把 MIME 类型、压缩、缓存这些配置做扎实这些细节决定了用户的第一印象。

相关新闻

tda-3.0.zip 拆包实录:线程转储分析工具实战

tda-3.0.zip 拆包实录:线程转储分析工具实战

简介:tda-3.0.zip 是一份面向拓扑数据分析(TDA)学习者与科研人员的开源库资源包,适合具备一定编程基础、希望将持久同调等拓扑方法应用于高维数据的研究者。资源围绕 Vietoris-Rips 与 Cech 复杂体、Wasserstein 距离等核心概念&a…

2026/10/13 4:35:08 阅读更多 →
K8S Master节点配置:从初始化到高可用的完整实践指南

K8S Master节点配置:从初始化到高可用的完整实践指南

1. 为什么“配置master节点”是K8S入门里最易被轻视的生死关卡很多人学K8S,一上来就猛敲kubeadm init,看到控制台刷出绿色Your Kubernetes control-plane has initialized successfully!就以为大功告成——结果第二天kubectl get nodes返回空列表&#x…

2026/10/13 4:35:08 阅读更多 →
JavaScript类型转换原理与实战:显式、隐式及常见坑点

JavaScript类型转换原理与实战:显式、隐式及常见坑点

写"js04"这篇时,我翻了翻早年的代码笔记,发现一个现象:很多人前面三篇(JS简介、数据类型、运算符)都看得津津有味,一到自己动手写功能,就在类型转化上翻车。最典型的两个问题&#xf…

2026/10/13 4:35:08 阅读更多 →

最新新闻

Open Code Review:一种透明、结构化、低摩擦的代码评审实践体系

Open Code Review:一种透明、结构化、低摩擦的代码评审实践体系

1. “Open Code Review”不是开源项目,而是一套可落地的代码评审实践体系“Open Code Review”这个词最近在技术社区里频繁出现,但很多人第一反应是——这又是个新出的开源工具?或者某个大厂刚开源的代码审查平台?其实都不是。它既…

2026/10/13 5:14:27 阅读更多 →
Python字典为什么有序?3.7插入顺序保证背后的哈希表实现与工程取舍

Python字典为什么有序?3.7插入顺序保证背后的哈希表实现与工程取舍

Python 3.6 刚发布那会儿,我把项目解释器版本从 3.5 升上来,第一件让我愣住的事不是 f-string,也不是 async/await 的完善,而是普通字典的打印顺序突然变了。以前每次跑 dict 输出出来的顺序都像抽奖,那次却和赋值的先…

2026/10/13 5:14:27 阅读更多 →
S变换短窗能量法:解决缆-线混合配电网故障选线难题

S变换短窗能量法:解决缆-线混合配电网故障选线难题

雷雨季节凌晨两点,某城区配电运维站的值班电话比闹钟还准。监控屏上,四条出线的零序电流同时跳了起来,哪一条是真正发生单相接地的故障线路,波形上看着都差不多,但只要拿尺子去比一组稳态幅值,很快就会发现…

2026/10/13 5:14:27 阅读更多 →
Agent技能独立化架构:让大模型从“能聊”到“能干活”的工程实践

Agent技能独立化架构:让大模型从“能聊”到“能干活”的工程实践

最近接了个活儿,要把一套“只会聊天”的对话系统升级成真正能帮忙干活的智能体。结果我发现,朋友圈里聊得火热的那个“agent-skills”项目,正好就是解决这类问题的关键拼图。这半年我在实际落地项目里反复折腾这套东西,把“技能”…

2026/10/13 5:14:27 阅读更多 →
Python字典为何从无序变有序:3.6紧凑哈希表到3.7规范保证的完整实证

Python字典为何从无序变有序:3.6紧凑哈希表到3.7规范保证的完整实证

Python 的字典到底有没有序?这个问题放到五年前,老手几乎会统一口径:无序,别依赖迭代顺序。而现在你再问同样的问题,答案已经完全反过来了——从 Python 3.7 开始,字典按键的插入顺序迭代,是语言…

2026/10/13 5:14:27 阅读更多 →
LiteLLM统一网关实战:搞定大模型API接入与模型切换难题

LiteLLM统一网关实战:搞定大模型API接入与模型切换难题

不知道你们有没有这种经历:项目对接了好几个模型服务商的API,每个服务商的鉴权方式不一样、返回结构不一样、限流策略也不一样。最难受的是,方案评审时说的是“随时可以切换模型”,真正切的时候才发现,切换一次要改几十…

2026/10/13 5:13:27 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →