fix(DLPilot): 投屏退出体验 — 替换语义 + 一键恢复桌面

This commit is contained in:
2026-09-14 14:55:30 +08:00
parent 8e8811a4a0
commit c1a5712f76
3 changed files with 33 additions and 5 deletions
Binary file not shown.
+4 -1
View File
@@ -94,6 +94,8 @@ class App(ctk.CTk):
self._tl_order = [] # 温度查询应答顺序: 'DMD'/'LAMP' 先到先得
self._build()
self._load_displays()
# 主窗口按 ESC 也能关闭所有投屏(投屏窗口失焦时的兜底出口)
self.bind('<Escape>', lambda _e: patterns.close_all())
if dlpc_rs485.HAS_SERIAL:
self._poll_dlpc()
if auto_close > 0:
@@ -208,7 +210,8 @@ class App(ctk.CTk):
self.edid_scroll.pack(fill='both', expand=True)
# -- 测试图案 --
card, c = self._card(col,'测试图案 — 黑底 1:1 居中, 按 ESC 退出')
card, c = self._card(col,'测试图案 — 黑底 1:1 居中, 投屏按 ESC "恢复桌面"退出',
button='恢复桌面', command=patterns.close_all)
card.grid(row=3, column=0, sticky='ew', pady=(10, 0))
row1 = ctk.CTkFrame(c, fg_color='transparent')
row1.pack(fill='x')
+29 -4
View File
@@ -9,6 +9,19 @@
from config import DEFAULT_AREA, HAS_PIL, Image, ImageTk, PAT_W, PAT_H
# 当前打开的投屏窗口集合: 支持"新图案替换旧图案"与 close_all() 一键恢复桌面
_OPEN = set()
def close_all():
"""关闭所有打开的投屏窗口, 恢复桌面"""
for top in list(_OPEN):
try:
top.destroy()
except Exception:
pass
_OPEN.clear()
PATTERN_NAMES = {'Red': '纯红', 'Green': '纯绿', 'Blue': '纯蓝',
'Checker': '黑白棋盘格', 'Grid': '网格线'}
@@ -43,8 +56,9 @@ def _area_box(spec, w, h):
def _open_fullscreen(parent, rect, auto_close=0):
"""创建覆盖 rect(x,y,w,h) 的无边框全屏黑底窗口, 返回 (top, cv)
只支持 ESC 退出: overrideredirect 窗口必须 focus_force 强取键盘焦点,
否则收不到按键(Windows 上该组合有效)。
ESC 退出(需窗口持有键盘焦点); overrideredirect 窗口必须 focus_force
强取键盘焦点, 否则收不到按键(Windows 上该组合有效)。
窗口登记进 _OPEN: 打开新投屏前会关旧的(替换语义), close_all() 一键全关。
"""
import tkinter as tk
rx, ry, rw, rh = rect
@@ -58,9 +72,16 @@ def _open_fullscreen(parent, rect, auto_close=0):
cv.pack(fill='both', expand=True)
def close(_evt=None):
_OPEN.discard(top)
top.destroy()
def _on_destroy(e):
if e.widget is top: # 子控件销毁也冒泡到此, 只认窗口本身
_OPEN.discard(top)
top.bind('<Escape>', close)
top.bind('<Destroy>', _on_destroy)
_OPEN.add(top)
if auto_close > 0:
top.after(auto_close * 1000, close)
top.focus_force()
@@ -68,7 +89,9 @@ def _open_fullscreen(parent, rect, auto_close=0):
def show_pattern(parent, rect, kind, auto_close=0, area=DEFAULT_AREA):
"""在 rect 指定的屏幕上全屏出居中测试卡(无任何 OSD 修饰), 区域由 area 指定"""
"""在 rect 指定的屏幕上全屏出居中测试卡(无任何 OSD 修饰), 区域由 area 指定
打开前先关闭已有投屏窗口(替换语义, 不会多层叠罗汉)。"""
close_all()
top, cv = _open_fullscreen(parent, rect, auto_close)
def draw(_evt=None):
@@ -107,7 +130,9 @@ def show_pattern(parent, rect, kind, auto_close=0, area=DEFAULT_AREA):
def show_pattern_image(parent, rect, path, auto_close=0, area=DEFAULT_AREA):
"""全屏黑底, 图片 1:1 居中于 area 指定的测试卡区域:
小于区域 -> 真实像素居中, 四周黑边;
大于区域 -> 等效从中心截取(区域外用黑矩形遮挡)"""
大于区域 -> 等效从中心截取(区域外用黑矩形遮挡)
打开前先关闭已有投屏窗口(替换语义)。"""
close_all()
top, cv = _open_fullscreen(parent, rect, auto_close)
def draw(_evt=None):