# -*- coding: utf-8 -*- """问题 5 取证:会话改名覆盖层(RenameOverlay)的"聚光灯"遮罩现状""" import os import sys import tempfile sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu" os.environ.setdefault("PYTHONIOENCODING", "utf-8") import core.db_manager as _dbm # noqa: E402 _dbm._DEFAULT_DB = os.path.join(tempfile.gettempdir(), f"haocode_q5_{os.getpid()}.db") _cfg = os.path.join(tempfile.gettempdir(), f"haocode_q5_{os.getpid()}.json") open(_cfg, "w", encoding="utf-8").write('{"providers": {}}') os.environ["HAOCODE_CONFIG_FILE"] = _cfg from PyQt6.QtWidgets import QApplication # noqa: E402 from PyQt6.QtTest import QTest # noqa: E402 from ui.views.main_window import MainWindow, RenameOverlay, SessionContextPopup # noqa: E402 app = QApplication(sys.argv) w = MainWindow() w.resize(1300, 900) w.show() for _ in range(40): app.processEvents() QTest.qWait(20) sid = w.db.create_session("聚光灯测试会话")["id"] w.load_messages_to_web(sid) for _ in range(20): app.processEvents() QTest.qWait(20) print("=== SessionContextPopup 是否为独立顶层窗口 ===") print(" windowFlags 含 Qt.Popup ?", bool(SessionContextPopup(sid, "", w).windowFlags() & 0x80000000)) pop = SessionContextPopup(sid, "聚光灯测试会话", w) print(" isWindow() =", pop.isWindow(), " windowType =", pop.windowFlags()) print() print("=== RenameOverlay 现状 ===") w._rename_session(sid) for _ in range(25): app.processEvents() QTest.qWait(20) ovs = [c for c in w.children() if isinstance(c, RenameOverlay)] if not ovs: print(" ✗ 没找到 RenameOverlay") else: ov = ovs[0] print(" 父对象 =", ov.parent().__class__.__name__) print(" isWindow() =", ov.isWindow(), " (False = 主窗口的子控件,只覆盖客户区)") print(" 几何 =", ov.geometry()) print(" 主窗口 rect =", w.rect(), " 主窗口 frameGeometry =", w.frameGeometry()) print(" WA_TranslucentBackground =", ov.testAttribute( __import__('PyQt6.QtCore', fromlist=['Qt']).Qt.WidgetAttribute.WA_TranslucentBackground)) print(" graphicsEffect =", type(ov.graphicsEffect()).__name__ if ov.graphicsEffect() else None) print(" 遮罩色 =", ov._overlay_color.getRgb()) print(" form 几何 =", ov.form.geometry(), " form 是否在遮罩内 =", ov.rect().contains(ov.form.geometry())) # 看遮罩是否盖住了标题栏 / 是否超出窗口 print(" 遮罩 top-left(全局) =", ov.mapToGlobal(ov.rect().topLeft()), " bottom-right(全局) =", ov.mapToGlobal(ov.rect().bottomRight())) print(" 主窗口(全局) =", w.mapToGlobal(w.rect().topLeft()), w.mapToGlobal(w.rect().bottomRight())) out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_tmp_q5_overlay.png") ov.grab().save(out) print(" 覆盖层截图 ->", out, ov.width(), "x", ov.height()) out2 = os.path.join(os.path.dirname(os.path.abspath(__file__)), "_tmp_q5_window.png") w.grab().save(out2) print(" 主窗口截图 ->", out2, w.width(), "x", w.height()) os.remove(_cfg)