# main.py import io import os import sys # ==================== 🌟 冻结/无控制台环境:stdout/stderr 安全化 ==================== # 🐛 打包成 exe 后踩到的真 bug(开发环境永远不会暴露): # 打包版没有控制台,sys.stdout 可能是 None 或编码为 GBK 的流 → # 任何 print 里的 emoji(🚀✅🛑…)都会抛 UnicodeEncodeError, # 而且是在 MainWindow() 之前就崩 → **主窗口根本不出现**。 # 统一改成 UTF-8 + errors=replace:打包版与开发版行为一致, # 即使控制台是 GBK,也只会显示成 '?' 而不会崩。 for _name in ("stdout", "stderr"): _s = getattr(sys, _name, None) if _s is None: try: setattr(sys, _name, open(os.devnull, "w", encoding="utf-8", errors="replace")) except Exception: pass continue try: _s.reconfigure(encoding="utf-8", errors="replace") except Exception: try: setattr(sys, _name, io.TextIOWrapper( _s.buffer, encoding="utf-8", errors="replace", line_buffering=True)) except Exception: pass # ==================== 🌟 WebEngine 渲染配置(必须在 PyQt6 导入之前设置)==================== # 本机实测渲染模式:GPU 硬件加速(ANGLE → Direct3D11, AMD 核显),非 CPU 软渲染。 # # 黑边/黑框背景(已实测): # Windows 上窗口缩放的新暴露区域未出帧时,GPU 合成器露出黑色、软件合成器露出白色。 # 基准数据(重度页面 500 节点+滚动+强制重绘): # GPU 合成 59.2 FPS(黑框) # 软件合成 30.1 FPS(白框,视觉反差小;轻量聊天页实测跟手无差别) # 因此默认采用“软件合成”(白框、好看);若遇重度页面掉帧,用 HAOCODE_COMPOSITING=gpu 回退。 # # ⚠️ 2026-07 重大变更:默认改为全 CPU 软渲染(--disable-gpu)。 # 原因:本机 AMD 核显 GPU 上下文周期性丢失(context lost 实测复现), # GPU 光栅化产物无法合成上屏 → 流式正文 DOM 已写入但屏幕不刷新。 # 软渲染在 Chromium 内全 CPU 完成,彻底绕开该故障模式;聊天页性能足够。 # # 备选开关(二选一,或直接设置 QTWEBENGINE_CHROMIUM_FLAGS 完全覆盖): # HAOCODE_RENDER=gpu → 旧默认:GPU 光栅化 + 软合成(需 GPU 驱动稳定) # HAOCODE_COMPOSITING=gpu → 回退 GPU 合成(黑框、满帧) if "QTWEBENGINE_CHROMIUM_FLAGS" not in os.environ: _render_mode = os.environ.get("HAOCODE_RENDER", "").strip().lower() _comp_mode = os.environ.get("HAOCODE_COMPOSITING", "soft").strip().lower() if _render_mode in ("gpu", "hardware"): # 旧默认:GPU 光栅化 + 软合成(仅当 GPU 驱动稳定时使用) _flags = ["--enable-gpu-rasterization", "--enable-zero-copy", "--ignore-gpu-blocklist"] if _comp_mode != "gpu": # 默认软合成:黑框→白框 _flags.append("--disable-gpu-compositing") os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = " ".join(_flags) else: # 默认(含 software):全 CPU 软渲染,规避 GPU 上下文丢失导致的不刷新 os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu" print(f"[渲染] QTWEBENGINE_CHROMIUM_FLAGS = {os.environ.get('QTWEBENGINE_CHROMIUM_FLAGS', '(未设置)')}", flush=True) from PyQt6.QtWidgets import QApplication from PyQt6.QtCore import Qt # 确保 Python 能找到项目根目录下的模块 sys.path.append(os.path.dirname(os.path.abspath(__file__))) # P1-03:Chromium sandbox 契约(在导入 PyQt6/QtWebEngine 前处理;renderer_backend 仅 stdlib) # - 默认保留 sandbox;--no-sandbox 仅在显式配置 + root/容器场景下接受(高可见警告) # - 普通桌面运行中的 --no-sandbox 被剥离并告警 from core import renderer_backend as _renderer_backend os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = _renderer_backend.sanitize_chromium_flags( os.environ["QTWEBENGINE_CHROMIUM_FLAGS"]) print(f"[渲染] 最终 QTWEBENGINE_CHROMIUM_FLAGS = {os.environ['QTWEBENGINE_CHROMIUM_FLAGS']!r}", flush=True) # 导入主窗口类 from ui.views.main_window import MainWindow def main(): # 1. 开启高 DPI 缩放支持 (让界面在 2K/4K 屏幕上不模糊) # PyQt6 默认已经处理得很好了,但加上这句更稳妥 if hasattr(Qt, 'AA_EnableHighDpiScaling'): QApplication.setAttribute(Qt.ApplicationAttribute.AA_EnableHighDpiScaling, True) if hasattr(Qt, 'AA_UseHighDpiPixmaps'): QApplication.setAttribute(Qt.ApplicationAttribute.AA_UseHighDpiPixmaps, True) # 2. 初始化 QApplication 实例 app = QApplication(sys.argv) # 极客细节:设置应用的全局字体 (可选) # font = app.font() # font.setFamily("Segoe UI") # Windows 推荐字体 # app.setFont(font) # 防御:若系统解析出的默认字体 pointSize 无效(<=0),补一个合法值, # 消除启动时 "QFont::setPointSize: Point size <= 0 (-1)" 的 Qt 警告(纯警告,非异常) _app_font = app.font() if _app_font.pointSize() <= 0: _app_font.setPointSize(9) app.setFont(_app_font) print("🚀 GeekAgent-Studio 正在启动...") print("--------------------------------------------------") # 3. 实例化主窗口 window = MainWindow() # 4. 显示窗口 window.show() # 5. 进入主事件循环,并安全退出 sys.exit(app.exec()) if __name__ == "__main__": main()