Files
kefu/deploy/dpi-adaptation-20260916/deliver.py
T
2026-09-21 10:34:06 +08:00

53 lines
4.1 KiB
Python
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.
from pathlib import Path
import ast,hashlib,json
folder=Path(__file__).resolve().parent;target=Path('C:/wechat_rpa');payload=folder/'payload'
doc=r'''# 高 DPI 与响应式界面修复(2026-09-16)
## 修复效果
- 「自动」跟随系统显示缩放,支持 100%、125%、200%、300% 等倍率。Qt 与内嵌网页各使用逻辑像素,不再把系统放大后的界面压回固定画布。
- 字体、SVG 图标、按钮、边距保持统一比例。长页面滚动;空间不足时卡片减少列数,导航区独立滚动,监听和设置入口保留在侧栏底部。
- 1080p、4K 和更高分辨率使用同一套逻辑布局。调整窗口高度和切换页面不会改变文字大小。
- 初始窗口按当前显示器可用区域设定;移动到另一显示器或改变显示设置后,窗口重新约束在可用区域内。已处理负坐标副屏和显示器移除事件。
- 修复原生 QBoxLayout、QGridLayout 的间距未跟随界面大小变化的问题。
## 使用
退出后从本目录重新运行 `python wechat_gui_qt.py`,进入「系统设置 → 界面大小」选择「自动」。以后直接调整 Windows 的显示缩放即可。
需要额外放大时可选择 100%–300%,相对于系统缩放立即生效,无需重启。恢复「自动」即可跟随系统。此设置不再写入进程级 `QT_SCALE_FACTOR`;开发者显式设置的环境变量仍由 Qt 正常处理。
这次更新的是协议目录源码及 UI 资源,已有 EXE/安装包未重新打包;旧 EXE 不会自动读取新源码。原监听、账号、聊天和协议配置没有被本次更新覆盖。
## 验证
- 138 项显示适配、Qt 控制台、悬浮胶囊、运行设置、模拟协议链路和打包路径测试通过。
- 8 个页面 × 7 种显示条件,共 56 组浏览器检查:无横向溢出、无页面脚本异常,含 125% 分数倍率、2 倍/3 倍和小窗口。
- 实际 Qt WebEngine 以 1、2、3 倍模拟 DPI 运行:960 逻辑像素宽的窗口分别输出 960、1920、2880 物理像素;Qt 与网页 DPR 一致,字体布局逻辑尺寸一致。
- 窗口换屏、负坐标屏幕、缩小可用区域及移除显示器通过模拟事件回归;本机未进行实体三显示器拖拽验收。
- 没有向真实客户发送测试消息。
## 文件与备份
主要文件:`wechat_gui_qt.py`、`assets/ui/console-app.js`、`assets/ui/console-responsive.css`、`assets/ui/zhenyang-ai-console.html`。
备份:`backups/dpi-adaptation-20260916`。哈希清单与测试结果:`UI_DPI_MANIFEST_20260916.json`。现有打包配置已包含整个 `assets/ui` 目录,新样式会随下次打包进入安装包。
技术依据:Qt 使用设备无关像素并按显示器 DPR 绘制,详见 [Qt High DPI](https://doc.qt.io/qt-6.8/highdpi.html)。页面采用参与布局计算的缩放及响应式栅格,详见 [CSS zoom](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/zoom)。
'''
(target/'UI_DPI_20260916.md').write_text(doc,encoding='utf-8',newline='\n')
record=json.loads((folder/'applied.json').read_text())
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
for row in record['manifest']:
path=target/row['path'];assert sha(path)==sha(payload/row['path']),row['path']
if path.suffix=='.py':ast.parse(path.read_text(encoding='utf-8'))
row['sha256']=sha(path)
browser=json.loads((folder/'qa/results.json').read_text())
assert len(browser['results'])==56 and not browser['errors']
assert all(r['contentWidth']<=r['mainWidth']+2 for r in browser['results'])
record.update(tests_passed=138,browser_checks=56,browser_errors=[],qt_dpi_checks=[json.loads((folder/'qa'/f'qt-{n}x.json').read_text()) for n in [1,2,3]],
installer_rebuilt=False,artifacts=str(folder),guide='UI_DPI_20260916.md')
(target/'UI_DPI_MANIFEST_20260916.json').write_text(json.dumps(record,ensure_ascii=False,indent=2),encoding='utf-8')
(folder/'final.json').write_text(json.dumps(record,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps({'files':len(record['manifest']),'tests':138,'browser_checks':56,'qt_dpi':[1,2,3],'backup':record['backup']},ensure_ascii=False))