Files
pqAutomationApp/app/views/panels/side_panels.py

395 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""侧边面板(日志 / Local Dimming / 调试)"""
import traceback
import tkinter as tk
import ttkbootstrap as ttk
from app.views.pq_log_gui import PQLogGUI
from app.views.pq_debug_panel import PQDebugPanel
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from pqAutomationApp import PQAutomationApp
def create_log_panel(self: "PQAutomationApp"):
"""创建日志面板"""
self.log_frame = ttk.Frame(self.content_frame)
self.log_gui = PQLogGUI(self.log_frame)
self.log_gui.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 默认隐藏日志面板
self.log_visible = False
# 注册到面板管理系统
self.register_panel(
"log", self.log_frame, None, "log_visible"
) # button会在后面设置
def create_local_dimming_panel(self: "PQAutomationApp"):
"""创建 Local Dimming 测试面板。"""
self.local_dimming_frame = ttk.Frame(self.content_frame)
# 主容器
main_container = ttk.Frame(self.local_dimming_frame, padding=10)
main_container.pack(fill=tk.BOTH, expand=True)
# ==================== 1. 标题 ====================
title_frame = ttk.Frame(main_container)
title_frame.pack(fill=tk.X, pady=(0, 10))
ttk.Label(
title_frame,
text="🔆 Local Dimming 窗口测试",
font=("微软雅黑", 14, "bold"),
).pack(side=tk.LEFT)
# ==================== 2. 窗口百分比按钮 ====================
window_frame = ttk.LabelFrame(
main_container, text="🔆 窗口百分比(点击发送)", padding=10
)
window_frame.pack(fill=tk.X, pady=(0, 10))
# 说明文字
ttk.Label(
window_frame,
text="点击按钮发送对应百分比的白色窗口(黑色背景 + 居中白色矩形)",
font=("", 9),
style="SuccessState.TLabel",
).pack(pady=(0, 8))
# 第一行1%, 2%, 5%, 10%, 18%
row1 = ttk.Frame(window_frame)
row1.pack(fill=tk.X, pady=(0, 5))
percentages_row1 = [1, 2, 5, 10, 18]
for p in percentages_row1:
ttk.Button(
row1,
text=f"{p}%",
command=lambda p=p: self.send_ld_window(p),
bootstyle="success",
width=12,
).pack(side=tk.LEFT, padx=3)
# 第二行25%, 50%, 75%, 100%
row2 = ttk.Frame(window_frame)
row2.pack(fill=tk.X)
percentages_row2 = [25, 50, 75, 100]
for p in percentages_row2:
ttk.Button(
row2,
text=f"{p}%",
command=lambda p=p: self.send_ld_window(p),
bootstyle="success",
width=12,
).pack(side=tk.LEFT, padx=3)
# ==================== 3. 其他手动图案 ====================
pattern_frame = ttk.LabelFrame(main_container, text="🧩 其他测试图案", padding=10)
pattern_frame.pack(fill=tk.X, pady=(0, 10))
ttk.Label(
pattern_frame,
text="手动发送棋盘格、瞬时峰值、黑场图案,再点击采集当前亮度",
font=("", 9),
style="SuccessState.TLabel",
).pack(pady=(0, 8))
pattern_row = ttk.Frame(pattern_frame)
pattern_row.pack(fill=tk.X)
ttk.Button(
pattern_row,
text="棋盘格(中心白)",
command=lambda: self.send_ld_checkerboard(True),
bootstyle="secondary",
width=14,
).pack(side=tk.LEFT, padx=3)
ttk.Button(
pattern_row,
text="棋盘格(中心黑)",
command=lambda: self.send_ld_checkerboard(False),
bootstyle="secondary",
width=14,
).pack(side=tk.LEFT, padx=3)
ttk.Button(
pattern_row,
text="瞬时峰值",
command=self.send_ld_instant_peak,
bootstyle="warning",
width=12,
).pack(side=tk.LEFT, padx=3)
ttk.Button(
pattern_row,
text="全黑画面",
command=self.send_ld_black_pattern,
bootstyle="dark",
width=12,
).pack(side=tk.LEFT, padx=3)
# ==================== 4. CA410 采集按钮 ====================
measure_frame = ttk.LabelFrame(main_container, text="📊 CA410 测量", padding=10)
measure_frame.pack(fill=tk.X, pady=(0, 10))
measure_btn_frame = ttk.Frame(measure_frame)
measure_btn_frame.pack(fill=tk.X)
self.ld_measure_btn = ttk.Button(
measure_btn_frame,
text="📏 采集当前亮度",
command=self.measure_ld_luminance,
bootstyle="primary",
width=15,
)
self.ld_measure_btn.pack(side=tk.LEFT, padx=(0, 5))
# 显示测量结果
self.ld_result_label = ttk.Label(
measure_btn_frame,
text="亮度: -- cd/m² | x: -- | y: --",
font=("Consolas", 10),
style="InfoState.TLabel",
)
self.ld_result_label.pack(side=tk.LEFT, padx=(10, 0))
# ==================== 5. 测试结果表格 ====================
result_frame = ttk.LabelFrame(main_container, text="📋 测试记录", padding=10)
result_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
# Treeview
columns = ("测试项目", "图案", "亮度/结果", "x", "y", "时间")
self.ld_tree = ttk.Treeview(
result_frame, columns=columns, show="headings", height=10
)
for col in columns:
self.ld_tree.heading(col, text=col)
if col == "测试项目":
self.ld_tree.column(col, width=120, anchor=tk.CENTER)
elif col == "图案":
self.ld_tree.column(col, width=140, anchor=tk.CENTER)
elif col == "亮度/结果":
self.ld_tree.column(col, width=110, anchor=tk.CENTER)
elif col == "时间":
self.ld_tree.column(col, width=120, anchor=tk.CENTER)
else:
self.ld_tree.column(col, width=100, anchor=tk.CENTER)
self.ld_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# 滚动条
scrollbar = ttk.Scrollbar(
result_frame, orient=tk.VERTICAL, command=self.ld_tree.yview
)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.ld_tree.configure(yscrollcommand=scrollbar.set)
# ==================== 6. 底部操作按钮 ====================
bottom_frame = ttk.Frame(main_container)
bottom_frame.pack(fill=tk.X)
self.ld_clear_btn = ttk.Button(
bottom_frame,
text="清空记录",
command=self.clear_ld_records,
bootstyle="danger-outline",
width=12,
)
self.ld_clear_btn.pack(side=tk.LEFT, padx=(0, 5))
self.ld_save_btn = ttk.Button(
bottom_frame,
text="💾 保存结果",
command=self.save_local_dimming_results,
bootstyle="info",
width=12,
)
self.ld_save_btn.pack(side=tk.LEFT)
# 默认隐藏
self.local_dimming_visible = False
# 注册到面板管理系统
self.register_panel(
"local_dimming",
self.local_dimming_frame,
None,
"local_dimming_visible",
)
# 初始化当前窗口百分比(用于记录)
self.current_ld_percentage = None
self.current_ld_test_item = None
self.current_ld_pattern_label = None
def toggle_local_dimming_panel(self: "PQAutomationApp"):
"""切换 Local Dimming 面板显示"""
self.show_panel("local_dimming")
def toggle_log_panel(self: "PQAutomationApp"):
"""切换日志面板的显示状态"""
self.show_panel("log")
# ---- 单步调试面板(统一实现) ----
DEBUG_PANEL_CONFIGS = {
"screen_module": {
"window_attr": "debug_window",
"btn_attr": "screen_debug_btn",
"title": " 单步调试面板",
"window_log_prefix": "",
"data_log_prefix": "屏模组",
"failure_data_label": "调试数据",
# (item_key, debug_key, (category, subkey), data_label, enable_desc)
"data_items": [
("gamma", "gamma", ("shared", "gray"), "灰阶", "Gamma 单步调试"),
("gamut", "rgb", ("gamut", "rgb"), "RGB", "RGB 单步调试"),
],
},
"sdr_movie": {
"window_attr": "sdr_debug_window",
"btn_attr": "sdr_debug_btn",
"title": " SDR 单步调试面板",
"window_log_prefix": "SDR ",
"data_log_prefix": "SDR",
"failure_data_label": "SDR 调试数据",
"data_items": [
("gamma", "gamma", ("shared", "gray"), "灰阶", "Gamma 单步调试"),
("accuracy", "accuracy", ("accuracy", "measured"), "色准", "色准单步调试"),
("gamut", "rgb", ("gamut", "rgb"), "RGB", "RGB 单步调试"),
],
},
"hdr_movie": {
"window_attr": "hdr_debug_window",
"btn_attr": "hdr_debug_btn",
"title": " HDR 单步调试面板",
"window_log_prefix": "HDR ",
"data_log_prefix": "HDR",
"failure_data_label": "HDR 调试数据",
"data_items": [
("eotf", "eotf", ("shared", "gray"), "灰阶", "EOTF 单步调试"),
("accuracy", "accuracy", ("accuracy", "measured"), "色准", "色准单步调试"),
("gamut", "rgb", ("gamut", "rgb"), "RGB", "RGB 单步调试"),
],
},
}
def _toggle_debug_panel(self: "PQAutomationApp", test_type):
"""打开/关闭对应测试类型的单步调试面板(独立窗口)。"""
cfg = DEBUG_PANEL_CONFIGS[test_type]
win_attr = cfg["window_attr"]
btn = getattr(self, cfg["btn_attr"])
wlp = cfg["window_log_prefix"]
# 如果窗口已存在且可见,关闭它
existing = getattr(self, win_attr, None)
if existing is not None and existing.winfo_exists():
existing.destroy()
btn.config(text="打开调试面板")
return
# 创建新窗口
win = ttk.Toplevel(self.root)
win.title(cfg["title"])
win.geometry("900x400")
win.transient(self.root)
setattr(self, win_attr, win)
# 调试面板容器
debug_container = ttk.Frame(win, padding=10)
debug_container.pack(fill=tk.BOTH, expand=True)
# 创建调试面板实例(不要对它调用 pack
debug_panel_instance = PQDebugPanel(debug_container, self)
# 重新启用调试(如果有数据)
try:
selected_items = self.get_selected_test_items()
dlp = cfg["data_log_prefix"]
# 显式按 test_type 拿历史结果,避免依赖"当前活跃"状态
results_store = getattr(self, "results", None)
results_obj = results_store.get(test_type) if results_store is not None else None
if results_obj is None:
self.log_gui.log(f"{dlp} 暂无 {test_type} 的测试结果,面板已打开", level="warning")
else:
for item_key, debug_key, (cat, sub), data_label, enable_desc in cfg["data_items"]:
if item_key not in selected_items:
continue
data = results_obj.get_intermediate_data(cat, sub)
if not data:
if test_type == "screen_module" and item_key == "gamma":
self.log_gui.log("没有可用的灰阶数据", level="error")
continue
self.log_gui.log(f" → 加载 {len(data)}{data_label}数据点", level="info")
debug_panel_instance.enable_debug(test_type, debug_key, data)
except Exception as e:
self.log_gui.log(f"加载{cfg['failure_data_label']}失败: {str(e)}", level="error")
self.log_gui.log(traceback.format_exc(), level="error")
btn.config(text="关闭调试面板")
def on_closing():
btn.config(text="打开调试面板")
getattr(self, win_attr).destroy()
win.protocol("WM_DELETE_WINDOW", on_closing)
win.update_idletasks()
def toggle_screen_debug_panel(self: "PQAutomationApp"):
_toggle_debug_panel(self, "screen_module")
def toggle_sdr_debug_panel(self: "PQAutomationApp"):
_toggle_debug_panel(self, "sdr_movie")
def toggle_hdr_debug_panel(self: "PQAutomationApp"):
_toggle_debug_panel(self, "hdr_movie")
def update_sidebar_selection(self: "PQAutomationApp"):
"""更新侧边栏按钮的选中状态"""
# 重置所有按钮样式为默认
self.screen_module_btn.configure(style="Sidebar.TButton")
self.sdr_movie_btn.configure(style="Sidebar.TButton")
self.hdr_movie_btn.configure(style="Sidebar.TButton")
self.local_dimming_btn.configure(style="Sidebar.TButton")
# 设置当前选中按钮的样式
current_type = self.test_type_var.get()
if current_type == "screen_module":
self.screen_module_btn.configure(style="SidebarSelected.TButton")
elif current_type == "sdr_movie":
self.sdr_movie_btn.configure(style="SidebarSelected.TButton")
elif current_type == "hdr_movie":
self.hdr_movie_btn.configure(style="SidebarSelected.TButton")
elif current_type == "local_dimming":
self.local_dimming_btn.configure(style="SidebarSelected.TButton")
class SidePanelsMixin:
"""由 tools/refactor_to_mixins.py 自动生成。
把本模块的自由函数挂到 PQAutomationApp 上,便于 F12 跳转与类型推断。
"""
create_log_panel = create_log_panel
create_local_dimming_panel = create_local_dimming_panel
toggle_local_dimming_panel = toggle_local_dimming_panel
toggle_log_panel = toggle_log_panel
_toggle_debug_panel = _toggle_debug_panel
toggle_screen_debug_panel = toggle_screen_debug_panel
toggle_sdr_debug_panel = toggle_sdr_debug_panel
toggle_hdr_debug_panel = toggle_hdr_debug_panel
update_sidebar_selection = update_sidebar_selection