修改calman灰阶点击异常、修改色准结果显示异常
This commit is contained in:
@@ -232,6 +232,62 @@ def _apply_calman_tree_style(self: "PQAutomationApp") -> None:
|
||||
self.calman_data_tree.configure(style="Calman.Treeview")
|
||||
|
||||
|
||||
def _calman_log(self: "PQAutomationApp", message: str, level: str = "info") -> None:
|
||||
"""统一输出 Calman 面板日志。"""
|
||||
logger = getattr(self, "log_gui", None)
|
||||
if logger is None:
|
||||
return
|
||||
self._dispatch_ui(self.log_gui.log, f"CALMAN: {message}", level)
|
||||
|
||||
|
||||
def _build_calman_config_summary(self: "PQAutomationApp") -> str:
|
||||
"""生成顶部配置摘要,跟随当前测试类型展示 UCD 参数。"""
|
||||
cfg = getattr(self, "config", None)
|
||||
test_type = getattr(cfg, "current_test_type", "screen_module")
|
||||
test_cfg = {}
|
||||
if cfg is not None:
|
||||
test_cfg = getattr(cfg, "current_test_types", {}).get(test_type, {})
|
||||
|
||||
if test_type == "screen_module":
|
||||
color_space = getattr(getattr(self, "screen_module_color_space_var", None), "get", lambda: test_cfg.get("colorimetry", "-"))()
|
||||
output_format = getattr(getattr(self, "screen_module_output_format_var", None), "get", lambda: test_cfg.get("color_format", "-"))()
|
||||
bit_depth = getattr(getattr(self, "screen_module_bit_depth_var", None), "get", lambda: f"{int(test_cfg.get('bpc', 8))}bit")()
|
||||
data_range = getattr(getattr(self, "screen_module_data_range_var", None), "get", lambda: test_cfg.get("data_range", "Full"))()
|
||||
timing = test_cfg.get("timing", "-")
|
||||
profile_name = "Screen"
|
||||
elif test_type == "sdr_movie":
|
||||
color_space = getattr(getattr(self, "sdr_color_space_var", None), "get", lambda: test_cfg.get("colorimetry", "-"))()
|
||||
output_format = getattr(getattr(self, "sdr_output_format_var", None), "get", lambda: test_cfg.get("color_format", "-"))()
|
||||
bit_depth = getattr(getattr(self, "sdr_bit_depth_var", None), "get", lambda: f"{int(test_cfg.get('bpc', 8))}bit")()
|
||||
data_range = getattr(getattr(self, "sdr_data_range_var", None), "get", lambda: test_cfg.get("data_range", "Full"))()
|
||||
timing = test_cfg.get("timing", "-")
|
||||
profile_name = "SDR"
|
||||
elif test_type == "hdr_movie":
|
||||
color_space = getattr(getattr(self, "hdr_color_space_var", None), "get", lambda: test_cfg.get("colorimetry", "-"))()
|
||||
output_format = getattr(getattr(self, "hdr_output_format_var", None), "get", lambda: test_cfg.get("color_format", "-"))()
|
||||
bit_depth = getattr(getattr(self, "hdr_bit_depth_var", None), "get", lambda: f"{int(test_cfg.get('bpc', 10))}bit")()
|
||||
data_range = getattr(getattr(self, "hdr_data_range_var", None), "get", lambda: test_cfg.get("data_range", "Limited"))()
|
||||
timing = test_cfg.get("timing", "-")
|
||||
profile_name = "HDR"
|
||||
else:
|
||||
color_space = test_cfg.get("colorimetry", "-")
|
||||
output_format = test_cfg.get("color_format", "-")
|
||||
bit_depth = test_cfg.get("bpc", "-")
|
||||
data_range = test_cfg.get("data_range", "-")
|
||||
timing = test_cfg.get("timing", "-")
|
||||
profile_name = test_type
|
||||
|
||||
return (
|
||||
f"Profile: {profile_name} | Timing: {timing} | CS: {color_space} | "
|
||||
f"Fmt: {output_format} | Depth: {bit_depth} | Range: {data_range}"
|
||||
)
|
||||
|
||||
|
||||
def _refresh_calman_config_summary(self: "PQAutomationApp") -> None:
|
||||
if hasattr(self, "calman_config_summary_var"):
|
||||
self.calman_config_summary_var.set(_build_calman_config_summary(self))
|
||||
|
||||
|
||||
def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
"""创建 CALMAN 风格灰阶测试面板,注册到 panel_manager。"""
|
||||
palette = _get_calman_palette()
|
||||
@@ -242,6 +298,7 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
self.calman_results = {}
|
||||
self.calman_stop_event = threading.Event()
|
||||
self.calman_running = False
|
||||
self.calman_patch_send_busy = False
|
||||
self.calman_current_level = None
|
||||
self.calman_last_record = None
|
||||
self.calman_last_step_seconds = None
|
||||
@@ -298,6 +355,15 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
)
|
||||
self.calman_elapsed_label.pack(side=tk.LEFT)
|
||||
|
||||
self.calman_config_summary_var = tk.StringVar(value="")
|
||||
self.calman_config_summary_label = ttk.Label(
|
||||
control_row,
|
||||
textvariable=self.calman_config_summary_var,
|
||||
foreground=palette["status_fg"],
|
||||
anchor=tk.W,
|
||||
)
|
||||
self.calman_config_summary_label.pack(side=tk.LEFT, padx=(12, 0), fill=tk.X, expand=True)
|
||||
|
||||
metrics_row = ttk.Frame(chart_frame)
|
||||
metrics_row.grid(row=2, column=0, sticky=tk.EW, pady=(2, 0))
|
||||
metrics_row.columnconfigure((0, 1, 2, 3), weight=1)
|
||||
@@ -478,7 +544,13 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
)
|
||||
|
||||
def _bind_click(widget, p=pct):
|
||||
widget.bind("<Button-1>", lambda _e, pp=p: send_patch(self, pp))
|
||||
def _on_click(_e, pp=p):
|
||||
send_patch(self, pp)
|
||||
# Prevent event bubbling from canvas -> parent cell, which would
|
||||
# otherwise trigger duplicated sends for a single click.
|
||||
return "break"
|
||||
|
||||
widget.bind("<Button-1>", _on_click)
|
||||
|
||||
for w in (cell, target_canvas):
|
||||
_bind_click(w)
|
||||
@@ -581,6 +653,7 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
right.bind("<Configure>", lambda _e: _adaptive_matrix_columns(self))
|
||||
|
||||
_refresh_metric_table(self)
|
||||
_refresh_calman_config_summary(self)
|
||||
_update_target_strip(self)
|
||||
_update_actual_strip(self)
|
||||
_redraw_calman_charts(self)
|
||||
@@ -592,6 +665,7 @@ def create_calman_panel(self: "PQAutomationApp") -> None:
|
||||
def toggle_calman_panel(self: "PQAutomationApp") -> None:
|
||||
"""切换 CALMAN 灰阶面板显示。"""
|
||||
self.show_panel("calman")
|
||||
_refresh_calman_config_summary(self)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -604,23 +678,43 @@ def send_patch(self: "PQAutomationApp", pct: int) -> None:
|
||||
if not self.signal_service.is_connected:
|
||||
messagebox.showwarning("提示", "请先连接 UCD323 设备")
|
||||
return
|
||||
if getattr(self, "calman_patch_send_busy", False):
|
||||
_calman_log(self, f"send busy, ignore click pct={pct}", "warning")
|
||||
self.calman_status_var.set("发送进行中,请稍候...")
|
||||
return
|
||||
|
||||
rgb_val = int(round(pct * 255 / 100))
|
||||
self.calman_current_level = pct
|
||||
self.calman_status_var.set(f"发送 {pct}%(RGB={rgb_val})...")
|
||||
_highlight_patch(self, pct)
|
||||
_refresh_calman_config_summary(self)
|
||||
_calman_log(self, f"click patch pct={pct}, rgb=({rgb_val}, {rgb_val}, {rgb_val})")
|
||||
self.calman_patch_send_busy = True
|
||||
|
||||
def worker():
|
||||
try:
|
||||
self.signal_service.send_solid_rgb((rgb_val, rgb_val, rgb_val))
|
||||
_calman_log(self, f"send_solid_rgb start pct={pct}")
|
||||
test_type = getattr(self.config, "current_test_type", "screen_module")
|
||||
if hasattr(self, "pattern_service") and self.pattern_service is not None:
|
||||
self.pattern_service.send_rgb(
|
||||
(rgb_val, rgb_val, rgb_val),
|
||||
test_type=test_type,
|
||||
)
|
||||
else:
|
||||
self.signal_service.send_solid_rgb((rgb_val, rgb_val, rgb_val))
|
||||
_calman_log(self, f"send_solid_rgb success pct={pct}")
|
||||
_calman_log(self, f"ucd profile applied test_type={test_type}")
|
||||
self._dispatch_ui(
|
||||
self.log_gui.log, f"CALMAN: 已发送 {pct}% 灰阶 (RGB={rgb_val})",
|
||||
"info",
|
||||
)
|
||||
self._dispatch_ui(self.calman_status_var.set, f"{pct}% 已发送")
|
||||
except Exception as exc:
|
||||
_calman_log(self, f"send_solid_rgb failed pct={pct}: {exc}", "error")
|
||||
self._dispatch_ui(self.log_gui.log, f"发送失败: {exc}", "error")
|
||||
self._dispatch_ui(self.calman_status_var.set, f"发送失败: {exc}")
|
||||
finally:
|
||||
self.calman_patch_send_busy = False
|
||||
|
||||
threading.Thread(target=worker, daemon=True).start()
|
||||
|
||||
@@ -693,14 +787,32 @@ def measure_current_patch(self: "PQAutomationApp") -> None:
|
||||
|
||||
def worker():
|
||||
t0 = time.perf_counter()
|
||||
_calman_log(self, f"measure start pct={pct}")
|
||||
self._dispatch_ui(self.calman_status_var.set, f"采集 {pct}% 中...")
|
||||
rec = _measure_once(self, pct)
|
||||
if rec is None:
|
||||
_calman_log(self, f"measure failed pct={pct}", "error")
|
||||
self._dispatch_ui(self.calman_status_var.set, "采集失败")
|
||||
return
|
||||
step_s = time.perf_counter() - t0
|
||||
self.calman_last_step_seconds = step_s
|
||||
self.calman_results[pct] = rec
|
||||
_calman_log(
|
||||
self,
|
||||
(
|
||||
"measure success pct={pct}, x={x:.4f}, y={y:.4f}, Y={Y:.3f}, "
|
||||
"cct={cct:.0f}, gamma={gamma:.3f}, de2000={de:.3f}, step={step:.2f}s"
|
||||
).format(
|
||||
pct=pct,
|
||||
x=rec["x"],
|
||||
y=rec["y"],
|
||||
Y=rec["Y"],
|
||||
cct=rec["cct"] if rec["cct"] == rec["cct"] else float("nan"),
|
||||
gamma=rec["gamma"] if rec["gamma"] == rec["gamma"] else float("nan"),
|
||||
de=rec["de2000"] if rec["de2000"] == rec["de2000"] else float("nan"),
|
||||
step=step_s,
|
||||
),
|
||||
)
|
||||
self._dispatch_ui(_apply_record_to_ui, self, rec)
|
||||
self._dispatch_ui(
|
||||
self.calman_status_var.set, f"{pct}% 采集完成 ({step_s:.2f}s)"
|
||||
@@ -726,15 +838,28 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
|
||||
settle = float(getattr(self, "pattern_settle_time", 0.4))
|
||||
self.calman_progress["value"] = 0
|
||||
self.calman_progress_var.set("0 / 0")
|
||||
_refresh_calman_config_summary(self)
|
||||
_calman_log(self, f"sequence start levels={len(self.calman_levels)}, settle={settle:.2f}s")
|
||||
|
||||
def worker():
|
||||
seq_t0 = time.perf_counter()
|
||||
try:
|
||||
test_type = getattr(self.config, "current_test_type", "screen_module")
|
||||
rgb_session = None
|
||||
if hasattr(self, "pattern_service") and self.pattern_service is not None:
|
||||
rgb_session = self.pattern_service.prepare_session(
|
||||
"rgb",
|
||||
test_type=test_type,
|
||||
log_details=False,
|
||||
)
|
||||
_calman_log(self, f"sequence ucd profile applied test_type={test_type}")
|
||||
|
||||
order = sorted(self.calman_levels, reverse=True)
|
||||
total = len(order)
|
||||
self._dispatch_ui(self.calman_progress_var.set, f"0 / {total}")
|
||||
for i, pct in enumerate(order, 1):
|
||||
if self.calman_stop_event.is_set():
|
||||
_calman_log(self, f"sequence stop requested at step={i-1}/{total}", "warning")
|
||||
self._dispatch_ui(self.log_gui.log, "已停止连续测试", "warning")
|
||||
break
|
||||
step_t0 = time.perf_counter()
|
||||
@@ -742,12 +867,20 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
|
||||
self._dispatch_ui(
|
||||
self.calman_status_var.set, f"[{i}/{total}] 发送 {pct}%"
|
||||
)
|
||||
_calman_log(self, f"sequence send step={i}/{total}, pct={pct}, rgb={rgb_val}")
|
||||
self._dispatch_ui(_highlight_patch, self, pct)
|
||||
try:
|
||||
self.signal_service.send_solid_rgb(
|
||||
(rgb_val, rgb_val, rgb_val)
|
||||
)
|
||||
if rgb_session is not None:
|
||||
self.pattern_service.send_rgb(
|
||||
(rgb_val, rgb_val, rgb_val),
|
||||
session=rgb_session,
|
||||
)
|
||||
else:
|
||||
self.signal_service.send_solid_rgb(
|
||||
(rgb_val, rgb_val, rgb_val)
|
||||
)
|
||||
except Exception as exc:
|
||||
_calman_log(self, f"sequence send failed step={i}/{total}, pct={pct}: {exc}", "error")
|
||||
self._dispatch_ui(
|
||||
self.log_gui.log, f"发送 {pct}% 失败: {exc}", "error"
|
||||
)
|
||||
@@ -755,11 +888,30 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
|
||||
self.calman_current_level = pct
|
||||
# 等待稳定,停止事件触发时尽快退出
|
||||
if self.calman_stop_event.wait(settle):
|
||||
_calman_log(self, f"sequence interrupted during settle step={i}/{total}, pct={pct}", "warning")
|
||||
break
|
||||
rec = _measure_once(self, pct)
|
||||
if rec is None:
|
||||
_calman_log(self, f"sequence measure failed step={i}/{total}, pct={pct}", "error")
|
||||
continue
|
||||
self.calman_results[pct] = rec
|
||||
_calman_log(
|
||||
self,
|
||||
(
|
||||
"sequence measure step={i}/{total}, pct={pct}, x={x:.4f}, y={y:.4f}, Y={Y:.3f}, "
|
||||
"cct={cct:.0f}, gamma={gamma:.3f}, de2000={de:.3f}"
|
||||
).format(
|
||||
i=i,
|
||||
total=total,
|
||||
pct=pct,
|
||||
x=rec["x"],
|
||||
y=rec["y"],
|
||||
Y=rec["Y"],
|
||||
cct=rec["cct"] if rec["cct"] == rec["cct"] else float("nan"),
|
||||
gamma=rec["gamma"] if rec["gamma"] == rec["gamma"] else float("nan"),
|
||||
de=rec["de2000"] if rec["de2000"] == rec["de2000"] else float("nan"),
|
||||
),
|
||||
)
|
||||
self._dispatch_ui(_apply_record_to_ui, self, rec)
|
||||
step_s = time.perf_counter() - step_t0
|
||||
total_s = time.perf_counter() - seq_t0
|
||||
@@ -772,9 +924,11 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
|
||||
total_s,
|
||||
)
|
||||
else:
|
||||
_calman_log(self, f"sequence complete total={total}")
|
||||
self._dispatch_ui(self.calman_status_var.set, "连续测试完成")
|
||||
self._dispatch_ui(self.log_gui.log, "CALMAN: 连续测试完成", "success")
|
||||
return
|
||||
_calman_log(self, "sequence stopped", "warning")
|
||||
self._dispatch_ui(self.calman_status_var.set, "已停止")
|
||||
finally:
|
||||
self.calman_running = False
|
||||
@@ -785,14 +939,17 @@ def start_sequence_test(self: "PQAutomationApp") -> None:
|
||||
def stop_sequence_test(self: "PQAutomationApp") -> None:
|
||||
"""请求停止连续测试。"""
|
||||
if self.calman_running:
|
||||
_calman_log(self, "stop requested", "warning")
|
||||
self.calman_stop_event.set()
|
||||
self.calman_status_var.set("正在停止...")
|
||||
else:
|
||||
_calman_log(self, "stop requested but no sequence is running", "warning")
|
||||
self.calman_status_var.set("当前没有运行中的连续测试")
|
||||
|
||||
|
||||
def clear_results(self: "PQAutomationApp") -> None:
|
||||
"""清空结果表和图表。"""
|
||||
_calman_log(self, "clear results")
|
||||
self.calman_results.clear()
|
||||
self.calman_last_record = None
|
||||
self.calman_reading_var.set(
|
||||
@@ -1135,6 +1292,8 @@ def refresh_calman_theme(self: "PQAutomationApp") -> None:
|
||||
|
||||
if hasattr(self, "calman_elapsed_label"):
|
||||
self.calman_elapsed_label.configure(foreground=palette["status_fg"])
|
||||
if hasattr(self, "calman_config_summary_label"):
|
||||
self.calman_config_summary_label.configure(foreground=palette["status_fg"])
|
||||
if hasattr(self, "calman_status_label"):
|
||||
self.calman_status_label.configure(foreground=palette["status_fg"])
|
||||
if hasattr(self, "calman_reading_summary_label"):
|
||||
@@ -1151,6 +1310,7 @@ def refresh_calman_theme(self: "PQAutomationApp") -> None:
|
||||
)
|
||||
|
||||
_refresh_metric_table(self)
|
||||
_refresh_calman_config_summary(self)
|
||||
_redraw_calman_charts(self)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user