Import the pre-repair source tree as the history baseline. Runtime data (data/), virtualenvs, bytecode caches and logs are gitignored so local secrets and user state stay out of the repo.
112 lines
4.9 KiB
Python
112 lines
4.9 KiB
Python
# 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__)))
|
||
|
||
# 导入主窗口类
|
||
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()
|