53 lines
4.1 KiB
Python
53 lines
4.1 KiB
Python
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))
|