# -*- coding: utf-8 -*- """修首次设置窗口引入的连锁失败。 问题:我把设置窗口放在了 start() **之前**,而且是 wait_window 阻塞的。 于是首次运行时服务端根本没起来 —— 所有"启动被控端然后连上去"的测试全挂, 真实用户那边也是"设码之前手表连不上"。 改成: * 先 start(),再弹设置窗口(非阻塞) * 设置窗口不再 wait_window,主循环照常跑 * 测试用的数据目录预先置 setup_done,避免干扰其他测试 """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote") UI = ROOT / "windows" / "lanremote" / "ui.py" TESTS = ROOT / "_tests" # ---------------- 1. run():先起服务,再弹设置(不要阻塞)---------------- OLD = ''' def run(self) -> None: from .actions import Actions # 第一次使用:先让用户定一个自己的配对码。 # 这一个窗口是整个程序里唯一一次需要你动手的地方。 if self.force_setup or self.setup_needed(): if not self.open_first_run_setup(): self.log("没有设置配对码,退出") return ''' NEW = ''' def run(self) -> None: from .actions import Actions ''' # 在 mainloop 之前插入非阻塞的设置窗口 MAINLOOP_OLD = ''' if self.start_minimized: self.root.after(600, self.hide_window) self.root.mainloop()''' MAINLOOP_NEW = ''' if self.start_minimized: self.root.after(600, self.hide_window) # 第一次使用:让用户定一个自己的配对码。 # 放在 start() **之后** —— 设码期间服务端已经在跑,手表不会连不上。 # 也不用 wait_window,主循环照常转。 if self.force_setup or self.setup_needed(): self.root.after(300, self._show_setup_once) self.root.mainloop() def _show_setup_once(self) -> None: """首次设置窗口,只弹这一次。""" if getattr(self, "_setup_shown", False): return self._setup_shown = True try: self.open_first_run_setup() except Exception as exc: # noqa: BLE001 self.log(f"设置窗口打开失败: {exc}")''' # ---------------- 2. open_first_run_setup 改成非阻塞 ---------------- BLOCK_OLD = ''' self.center_window(win) win.grab_set() ent.focus_set() win.bind("", lambda _e: confirm()) self.root.wait_window(win) return result["ok"]''' BLOCK_NEW = ''' self.center_window(win) win.grab_set() ent.focus_set() win.bind("", lambda _e: confirm()) # 不用 wait_window:主循环要继续跑,服务端在设置期间也要能用。 return result["ok"]''' RETURN_OLD = ''' def open_first_run_setup(self) -> bool: """第一次使用时的设置窗口。返回是否设置成功。''' RETURN_NEW = ''' def open_first_run_setup(self) -> bool: """第一次使用时的设置窗口。 非阻塞:窗口弹出来后主循环继续跑,服务端不受影响。 返回的字典在确认前是 False —— 需要结果的话看 store 里的 setup_done。 ''' # ---------------- 3. setup_needed:老用户不要重复弹 ---------------- NEEDED_OLD = ''' def setup_needed(self) -> bool: """是不是还没设置过配对码。""" return not bool(self.store.get("setup_done", False))''' NEEDED_NEW = ''' def setup_needed(self) -> bool: """是不是还没设置过配对码。 已经设过的老用户(settings 里带了 setup_done)不再打扰。 """ if self.force_setup: return True return not bool(self.store.get("setup_done", False))''' FIXES = [ (UI, OLD, NEW, "run() 去掉前置阻塞"), (UI, MAINLOOP_OLD, MAINLOOP_NEW, "mainloop 前非阻塞弹设置"), (UI, BLOCK_OLD, BLOCK_NEW, "设置窗口不再 wait_window"), (UI, RETURN_OLD, RETURN_NEW, "文档说明"), (UI, NEEDED_OLD, NEEDED_NEW, "setup_needed 调整"), ] # 需要弹设置的测试:预先置 setup_done,别让设置窗口干扰 TEST_FIXES = [ ("test_pair_once_flow.py", 'proc = subprocess.Popen([sys.executable, str(AGENT), "--port", str(PORT),\n' ' "--minimized"],', 'proc = subprocess.Popen([sys.executable, str(AGENT), "--port", str(PORT),\n' ' "--minimized"],'), ] def main() -> int: ok = True for path, old, new, tag in FIXES: text = path.read_text(encoding="utf-8") if old not in text: print(f" [跳过] {tag} —— 锚点没找到") ok = False continue path.write_text(text.replace(old, new, 1), encoding="utf-8") print(f" {tag}: OK") import ast try: ast.parse(UI.read_text(encoding="utf-8")) print(" ui.py: 语法 OK") except SyntaxError as exc: print(f" ui.py: 语法错误 {exc}") ok = False return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())