| 944 | |
| 945 | |
| 946 | class ControlApp: |
| 947 | REFRESH_MS = 15000 |
| 948 | |
| 949 | def __init__(self) -> None: |
| 950 | if tk is None: |
| 951 | raise RuntimeError("当前 Python 环境缺少 tkinter,无法显示桌面界面") |
| 952 | |
| 953 | self.root = tk.Tk() |
| 954 | self.root.title(APP_TITLE) |
| 955 | self.root.geometry("1260x900") |
| 956 | self.root.minsize(1120, 800) |
| 957 | self.root.configure(bg="#eef3f8") |
| 958 | |
| 959 | self.status_text = tk.StringVar(value="就绪") |
| 960 | self.last_refresh_text = tk.StringVar(value="尚未刷新") |
| 961 | self.local_url_text = tk.StringVar(value=f"本地面板:{LOCAL_PANEL_URL}") |
| 962 | self.remote_url_text = tk.StringVar(value="远程地址:未开启") |
| 963 | self.block_labels: list[dict[str, tk.Label]] = [] |
| 964 | self.metric_widgets: dict[str, dict[str, Any]] = {} |
| 965 | self.pending_approval_items: list[dict[str, Any]] = [] |
| 966 | self.selected_approval_token: str | None = None |
| 967 | self._busy = False |
| 968 | |
| 969 | self._build_ui() |
| 970 | self.refresh_status() |
| 971 | |
| 972 | def _build_ui(self) -> None: |
| 973 | container = tk.Frame(self.root, bg="#eef3f8") |
| 974 | container.pack(fill="both", expand=True, padx=14, pady=14) |
| 975 | |
| 976 | title = tk.Label( |
| 977 | container, |
| 978 | text=APP_TITLE, |
| 979 | font=("Microsoft YaHei UI", 22, "bold"), |
| 980 | bg="#eef3f8", |
| 981 | fg="#112033", |
| 982 | ) |
| 983 | title.pack(anchor="w") |
| 984 | |
| 985 | subtitle = tk.Label( |
| 986 | container, |
| 987 | text="用于在电脑端一键控制 Codex 服务,并集中查看本机服务、远程发布与手机连接状态。", |
| 988 | font=("Microsoft YaHei UI", 10), |
| 989 | bg="#eef3f8", |
| 990 | fg="#4f6072", |
| 991 | ) |
| 992 | subtitle.pack(anchor="w", pady=(4, 10)) |
| 993 | |
| 994 | endpoint_bar = tk.Frame(container, bg="#dbe8f6", bd=1, relief="solid") |
| 995 | endpoint_bar.pack(fill="x", pady=(0, 12)) |
| 996 | tk.Label( |
| 997 | endpoint_bar, |
| 998 | textvariable=self.local_url_text, |
| 999 | font=("Microsoft YaHei UI", 10, "bold"), |
| 1000 | bg="#dbe8f6", |
| 1001 | fg="#17324d", |
| 1002 | ).pack(anchor="w", padx=12, pady=(10, 2)) |
| 1003 | tk.Label( |