"""CCT 参数面板及其处理函数(与主文件重构版本保持同步)。""" import time import traceback from tkinter import messagebox import tkinter as tk import ttkbootstrap as ttk import algorithm.pq_algorithm as pq_algorithm def create_cct_params_frame(self): """创建色度参数设置区域 - 屏模组、SDR、HDR 独立(增加色域参考标准选择 + 单步调试按钮)""" # ==================== 屏模组色度参数 Frame ==================== self.cct_params_frame = ttk.LabelFrame( self.test_items_frame, text="色度参数设置(屏模组)" ) # 默认值 screen_default_cct_params = self.config.get_default_cct_params("screen_module") # 从配置读取屏模组参数 saved_params = self.config.current_test_types.get("screen_module", {}).get( "cct_params", screen_default_cct_params.copy() ) # 色域参考标准 saved_gamut_ref = self.config.current_test_types.get("screen_module", {}).get( "gamut_reference", self.config.get_default_gamut_reference("screen_module") ) # 创建屏模组变量 self.cct_x_ideal_var = tk.StringVar( value=str(saved_params.get("x_ideal", 0.3127)) ) self.cct_x_tolerance_var = tk.StringVar( value=str(saved_params.get("x_tolerance", 0.003)) ) self.cct_y_ideal_var = tk.StringVar( value=str(saved_params.get("y_ideal", 0.3290)) ) self.cct_y_tolerance_var = tk.StringVar( value=str(saved_params.get("y_tolerance", 0.003)) ) self.screen_gamut_ref_var = tk.StringVar(value=saved_gamut_ref) # 创建屏模组输入框(左侧:色度参数) params = [ ("x-ideal:", self.cct_x_ideal_var, "x_ideal"), ("x-tolerance:", self.cct_x_tolerance_var, "x_tolerance"), ("y-ideal:", self.cct_y_ideal_var, "y_ideal"), ("y-tolerance:", self.cct_y_tolerance_var, "y_tolerance"), ] for i, (label_text, var, key) in enumerate(params): ttk.Label(self.cct_params_frame, text=label_text).grid( row=i, column=0, sticky=tk.W, padx=5, pady=3 ) entry = ttk.Entry(self.cct_params_frame, textvariable=var, width=15) entry.grid(row=i, column=1, sticky=tk.W, padx=5, pady=3) # 绑定失去焦点事件 default_val = screen_default_cct_params[key] entry.bind( "", lambda e, v=var, d=default_val: self.on_cct_param_focus_out(v, d), ) # 色域参考标准选择(右侧第一行) ttk.Label(self.cct_params_frame, text="色域参考标准:").grid( row=0, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) screen_gamut_combo = ttk.Combobox( self.cct_params_frame, textvariable=self.screen_gamut_ref_var, values=["BT.2020", "BT.709", "DCI-P3"], state="disabled", width=12, ) screen_gamut_combo.grid(row=0, column=3, sticky=tk.W, padx=5, pady=3) screen_gamut_combo.bind( "<>", self.on_screen_gamut_ref_changed ) self.screen_gamut_combo = screen_gamut_combo # ==================== 单步调试按钮(右侧第二行)==================== ttk.Label(self.cct_params_frame, text="单步调试:").grid( row=1, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) self.screen_debug_btn = ttk.Button( self.cct_params_frame, text="打开调试面板", command=self.toggle_screen_debug_panel, bootstyle="info-outline", state=tk.DISABLED, # 初始禁用 width=15, ) self.screen_debug_btn.grid(row=1, column=3, sticky=tk.W, padx=5, pady=3) # 重新计算按钮(屏模组) self.recalc_cct_btn = ttk.Button( self.cct_params_frame, text="应用新参数并重绘", command=self.recalculate_cct, bootstyle="success", ) self.recalc_cct_btn.grid( row=4, column=0, columnspan=2, pady=10, padx=5, sticky="ew" ) self.recalc_cct_btn.grid_remove() # 色域重新计算按钮 self.recalc_gamut_btn = ttk.Button( self.cct_params_frame, text="应用色域参考并重绘", command=self.recalculate_gamut, bootstyle="warning", ) self.recalc_gamut_btn.grid( row=4, column=2, columnspan=2, pady=10, padx=5, sticky="ew" ) self.recalc_gamut_btn.grid_remove() # 提示文字 ttk.Label( self.cct_params_frame, text="提示: 清空输入框将恢复默认值", font=("SimHei", 8), foreground="gray", ).grid(row=5, column=0, columnspan=4, sticky=tk.W, padx=5, pady=5) # ==================== SDR 色度参数 Frame ==================== self.sdr_cct_params_frame = ttk.LabelFrame( self.test_items_frame, text="色度参数设置(SDR)" ) # SDR 默认值 sdr_default_cct_params = self.config.get_default_cct_params("sdr_movie") # 从配置读取 SDR 参数 sdr_saved_params = self.config.current_test_types.get("sdr_movie", {}).get( "cct_params", sdr_default_cct_params.copy() ) # 色域参考标准 sdr_saved_gamut_ref = self.config.current_test_types.get("sdr_movie", {}).get( "gamut_reference", self.config.get_default_gamut_reference("sdr_movie") ) # 创建 SDR 变量 self.sdr_cct_x_ideal_var = tk.StringVar( value=str(sdr_saved_params.get("x_ideal", 0.3127)) ) self.sdr_cct_x_tolerance_var = tk.StringVar( value=str(sdr_saved_params.get("x_tolerance", 0.003)) ) self.sdr_cct_y_ideal_var = tk.StringVar( value=str(sdr_saved_params.get("y_ideal", 0.3290)) ) self.sdr_cct_y_tolerance_var = tk.StringVar( value=str(sdr_saved_params.get("y_tolerance", 0.003)) ) self.sdr_gamut_ref_var = tk.StringVar(value=sdr_saved_gamut_ref) # 创建 SDR 输入框 sdr_params = [ ("x-ideal:", self.sdr_cct_x_ideal_var, "x_ideal"), ("x-tolerance:", self.sdr_cct_x_tolerance_var, "x_tolerance"), ("y-ideal:", self.sdr_cct_y_ideal_var, "y_ideal"), ("y-tolerance:", self.sdr_cct_y_tolerance_var, "y_tolerance"), ] for i, (label_text, var, key) in enumerate(sdr_params): ttk.Label(self.sdr_cct_params_frame, text=label_text).grid( row=i, column=0, sticky=tk.W, padx=5, pady=3 ) entry = ttk.Entry(self.sdr_cct_params_frame, textvariable=var, width=15) entry.grid(row=i, column=1, sticky=tk.W, padx=5, pady=3) # 绑定失去焦点事件 default_val = sdr_default_cct_params[key] entry.bind( "", lambda e, v=var, d=default_val: self.on_sdr_cct_param_focus_out(v, d), ) # 色域参考标准选择(右侧第一行) ttk.Label(self.sdr_cct_params_frame, text="色域参考标准:").grid( row=0, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) sdr_gamut_combo = ttk.Combobox( self.sdr_cct_params_frame, textvariable=self.sdr_gamut_ref_var, values=["BT.2020", "BT.709", "DCI-P3"], state="disabled", width=12, ) sdr_gamut_combo.grid(row=0, column=3, sticky=tk.W, padx=5, pady=3) sdr_gamut_combo.bind("<>", self.on_sdr_gamut_ref_changed) self.sdr_gamut_combo = sdr_gamut_combo # ==================== SDR 单步调试按钮(右侧第二行)==================== ttk.Label(self.sdr_cct_params_frame, text="单步调试:").grid( row=1, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) self.sdr_debug_btn = ttk.Button( self.sdr_cct_params_frame, text="打开调试面板", command=self.toggle_sdr_debug_panel, bootstyle="info-outline", state=tk.DISABLED, # 初始禁用 width=15, ) self.sdr_debug_btn.grid(row=1, column=3, sticky=tk.W, padx=5, pady=3) # 重新计算按钮(SDR) self.sdr_recalc_cct_btn = ttk.Button( self.sdr_cct_params_frame, text="应用新参数并重绘", command=self.recalculate_cct, bootstyle="success", ) self.sdr_recalc_cct_btn.grid( row=4, column=0, columnspan=2, pady=10, padx=5, sticky="ew" ) self.sdr_recalc_cct_btn.grid_remove() # 色域重新计算按钮(SDR) self.sdr_recalc_gamut_btn = ttk.Button( self.sdr_cct_params_frame, text="应用色域参考并重绘", command=self.recalculate_gamut, bootstyle="warning", ) self.sdr_recalc_gamut_btn.grid( row=4, column=2, columnspan=2, pady=10, padx=5, sticky="ew" ) self.sdr_recalc_gamut_btn.grid_remove() # 提示文字 ttk.Label( self.sdr_cct_params_frame, text="提示: 清空输入框将恢复默认值", font=("SimHei", 8), foreground="gray", ).grid(row=5, column=0, columnspan=4, sticky=tk.W, padx=5, pady=5) # ==================== HDR 色度参数 Frame ==================== self.hdr_cct_params_frame = ttk.LabelFrame( self.test_items_frame, text="色度参数设置(HDR)" ) # HDR 默认值 hdr_default_cct_params = self.config.get_default_cct_params("hdr_movie") # 从配置读取 HDR 参数 hdr_saved_params = self.config.current_test_types.get("hdr_movie", {}).get( "cct_params", hdr_default_cct_params.copy() ) # 色域参考标准 hdr_saved_gamut_ref = self.config.current_test_types.get("hdr_movie", {}).get( "gamut_reference", self.config.get_default_gamut_reference("hdr_movie") ) # 创建 HDR 变量 self.hdr_cct_x_ideal_var = tk.StringVar( value=str(hdr_saved_params.get("x_ideal", 0.3127)) ) self.hdr_cct_x_tolerance_var = tk.StringVar( value=str(hdr_saved_params.get("x_tolerance", 0.003)) ) self.hdr_cct_y_ideal_var = tk.StringVar( value=str(hdr_saved_params.get("y_ideal", 0.3290)) ) self.hdr_cct_y_tolerance_var = tk.StringVar( value=str(hdr_saved_params.get("y_tolerance", 0.003)) ) self.hdr_gamut_ref_var = tk.StringVar(value=hdr_saved_gamut_ref) # 创建 HDR 输入框 hdr_params = [ ("x-ideal:", self.hdr_cct_x_ideal_var, "x_ideal"), ("x-tolerance:", self.hdr_cct_x_tolerance_var, "x_tolerance"), ("y-ideal:", self.hdr_cct_y_ideal_var, "y_ideal"), ("y-tolerance:", self.hdr_cct_y_tolerance_var, "y_tolerance"), ] for i, (label_text, var, key) in enumerate(hdr_params): ttk.Label(self.hdr_cct_params_frame, text=label_text).grid( row=i, column=0, sticky=tk.W, padx=5, pady=3 ) entry = ttk.Entry(self.hdr_cct_params_frame, textvariable=var, width=15) entry.grid(row=i, column=1, sticky=tk.W, padx=5, pady=3) # 绑定失去焦点事件 default_val = hdr_default_cct_params[key] entry.bind( "", lambda e, v=var, d=default_val: self.on_hdr_cct_param_focus_out(v, d), ) # 色域参考标准选择(右侧第一行) ttk.Label(self.hdr_cct_params_frame, text="色域参考标准:").grid( row=0, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) hdr_gamut_combo = ttk.Combobox( self.hdr_cct_params_frame, textvariable=self.hdr_gamut_ref_var, values=["BT.2020", "BT.709", "DCI-P3"], state="disabled", width=12, ) hdr_gamut_combo.grid(row=0, column=3, sticky=tk.W, padx=5, pady=3) hdr_gamut_combo.bind("<>", self.on_hdr_gamut_ref_changed) self.hdr_gamut_combo = hdr_gamut_combo # ==================== HDR 单步调试按钮(右侧第二行)==================== ttk.Label(self.hdr_cct_params_frame, text="单步调试:").grid( row=1, column=2, sticky=tk.W, padx=(20, 5), pady=3 ) self.hdr_debug_btn = ttk.Button( self.hdr_cct_params_frame, text="打开调试面板", command=self.toggle_hdr_debug_panel, bootstyle="info-outline", state=tk.DISABLED, # 初始禁用 width=15, ) self.hdr_debug_btn.grid(row=1, column=3, sticky=tk.W, padx=5, pady=3) # 重新计算按钮(HDR) self.hdr_recalc_cct_btn = ttk.Button( self.hdr_cct_params_frame, text="应用新参数并重绘", command=self.recalculate_cct, bootstyle="success", ) self.hdr_recalc_cct_btn.grid( row=4, column=0, columnspan=2, pady=10, padx=5, sticky="ew" ) self.hdr_recalc_cct_btn.grid_remove() # 色域重新计算按钮(HDR) self.hdr_recalc_gamut_btn = ttk.Button( self.hdr_cct_params_frame, text="应用色域参考并重绘", command=self.recalculate_gamut, bootstyle="warning", ) self.hdr_recalc_gamut_btn.grid( row=4, column=2, columnspan=2, pady=10, padx=5, sticky="ew" ) self.hdr_recalc_gamut_btn.grid_remove() # 提示文字 ttk.Label( self.hdr_cct_params_frame, text="提示: 清空输入框将恢复默认值", font=("SimHei", 8), foreground="gray", ).grid(row=5, column=0, columnspan=4, sticky=tk.W, padx=5, pady=5) def _get_cct_var_dict(self, test_type): """按测试类型返回 CCT 变量映射。""" if test_type == "sdr_movie": return { "x_ideal": self.sdr_cct_x_ideal_var, "x_tolerance": self.sdr_cct_x_tolerance_var, "y_ideal": self.sdr_cct_y_ideal_var, "y_tolerance": self.sdr_cct_y_tolerance_var, } if test_type == "hdr_movie": return { "x_ideal": self.hdr_cct_x_ideal_var, "x_tolerance": self.hdr_cct_x_tolerance_var, "y_ideal": self.hdr_cct_y_ideal_var, "y_tolerance": self.hdr_cct_y_tolerance_var, } return { "x_ideal": self.cct_x_ideal_var, "x_tolerance": self.cct_x_tolerance_var, "y_ideal": self.cct_y_ideal_var, "y_tolerance": self.cct_y_tolerance_var, } def _parse_cct_float(self, var, default): """读取并解析 CCT 输入值,失败时回落默认值。""" try: value = var.get().strip() if value == "": return default return float(value) except Exception: return default def _save_cct_params_for(self, test_type): """保存指定测试类型的 CCT 参数。""" try: default_params = self.config.get_default_cct_params(test_type) var_dict = _get_cct_var_dict(test_type) cct_params = { key: _parse_cct_float(var_dict[key], default_params[key]) for key in default_params } if test_type not in self.config.current_test_types: self.config.current_test_types[test_type] = {} self.config.current_test_types[test_type]["cct_params"] = cct_params self.save_pq_config() except Exception: pass def _handle_cct_focus_out(self, var, default_value, save_func, label): """统一处理 CCT 参数失焦校验并保存。""" try: value = var.get().strip() if value == "": var.set(str(default_value)) if hasattr(self, "log_gui"): self.log_gui.log(f"{label} 参数为空,恢复默认值: {default_value}", level="success") else: try: float_val = float(value) if float_val < 0 or float_val > 1: var.set(str(default_value)) if hasattr(self, "log_gui"): self.log_gui.log( f"{label} 参数超出范围,恢复默认值: {default_value}" , level="error") except ValueError: var.set(str(default_value)) if hasattr(self, "log_gui"): self.log_gui.log( f"{label} 参数无效,恢复默认值: {default_value}" , level="error") save_func() except Exception as e: if hasattr(self, "log_gui"): self.log_gui.log(f"处理 {label} 参数失败: {str(e)}", level="error") def on_sdr_cct_param_focus_out(self, var, default_value): """SDR 色度参数失去焦点时的处理。""" _handle_cct_focus_out(var, default_value, self.save_sdr_cct_params, "SDR") def save_sdr_cct_params(self): """保存 SDR 色度参数。""" _save_cct_params_for("sdr_movie") def on_hdr_cct_param_focus_out(self, var, default_value): """HDR 色度参数失去焦点时的处理。""" _handle_cct_focus_out(var, default_value, self.save_hdr_cct_params, "HDR") def save_hdr_cct_params(self): """保存 HDR 色度参数。""" _save_cct_params_for("hdr_movie") def recalculate_cct(self): """重新计算并绘制色度图""" try: # 1. 保存新参数 self.save_cct_params() self.log_gui.log("色度参数已更新", level="success") # 2. 收起配置项 if hasattr(self, "config_panel_frame"): try: if self.config_panel_frame.winfo_viewable(): self.config_panel_frame.btn.invoke() self.root.update_idletasks() time.sleep(0.1) except: pass # 3. 跳转到色度图Tab self.chart_notebook.select(self.cct_chart_frame) self.root.update_idletasks() # 4. 检查是否有数据 if not hasattr(self, "results") or not self.results: self.log_gui.log("没有测试数据,无法重新绘制", level="error") messagebox.showwarning("警告", "请先完成测试后再重新计算") return # 5. 获取保存的灰阶数据 gray_data = self.results.get_intermediate_data("shared", "gray") if not gray_data: gray_data = self.results.get_intermediate_data("cct", "gray") if not gray_data or len(gray_data) < 2: self.log_gui.log("没有可用的灰阶数据", level="error") messagebox.showwarning("警告", "没有找到色度测试数据") return # 6. 重新计算 CCT self.log_gui.log("=" * 50, level="separator") self.log_gui.log("开始重新计算色度一致性...", level="info") self.log_gui.log("=" * 50, level="separator") cct_values = pq_algorithm.calculate_cct_from_results(gray_data) # 7. 更新结果 self.results.set_test_item_result("cct", {"cct_values": cct_values}) # 8. 重新绘制色度图 test_type = self.config.current_test_type self.plot_cct(test_type) self.log_gui.log("色度图已重新绘制", level="success") self.log_gui.log("=" * 50, level="separator") messagebox.showinfo("成功", "色度图已根据新参数重新绘制!") except Exception as e: self.log_gui.log(f"重新计算失败: {str(e)}", level="error") self.log_gui.log(traceback.format_exc(), level="error") messagebox.showerror("错误", f"重新计算失败: {str(e)}") def recalculate_gamut(self): """重新计算并绘制色域图(使用新的参考标准)""" try: # 1. 收起配置项 if hasattr(self, "config_panel_frame"): try: if self.config_panel_frame.winfo_viewable(): self.config_panel_frame.btn.invoke() self.root.update_idletasks() time.sleep(0.1) except: pass # 2. 跳转到色域图Tab self.chart_notebook.select(self.gamut_chart_frame) self.root.update_idletasks() # 3. 检查是否有数据 if not hasattr(self, "results") or not self.results: self.log_gui.log("没有测试数据,无法重新绘制", level="error") messagebox.showwarning("警告", "请先完成测试后再重新计算") return # 4. 获取保存的色域数据 rgb_data = self.results.get_intermediate_data("gamut", "rgb") if not rgb_data or len(rgb_data) < 3: self.log_gui.log("没有可用的色域数据", level="error") messagebox.showwarning("警告", "没有找到色域测试数据") return # 5. 获取当前测试类型 test_type = self.config.current_test_type # 6. 获取用户选择的参考标准 if test_type == "screen_module": reference_standard = self.screen_gamut_ref_var.get() elif test_type == "sdr_movie": reference_standard = self.sdr_gamut_ref_var.get() elif test_type == "hdr_movie": reference_standard = self.hdr_gamut_ref_var.get() else: reference_standard = "DCI-P3" self.log_gui.log("=" * 50, level="separator") self.log_gui.log(f"开始重新计算色域(参考标准: {reference_standard})...", level="info") self.log_gui.log("=" * 50, level="separator") # 7. 重新计算 XY 色域覆盖率 xy_points = [[result[0], result[1]] for result in rgb_data] # 根据参考标准计算 XY 覆盖率 if reference_standard == "BT.2020": area_xy, coverage_xy = pq_algorithm.calculate_gamut_coverage_BT2020( xy_points ) elif reference_standard == "BT.709": area_xy, coverage_xy = pq_algorithm.calculate_gamut_coverage_BT709( xy_points ) elif reference_standard == "DCI-P3": area_xy, coverage_xy = pq_algorithm.calculate_gamut_coverage_DCIP3( xy_points ) else: area_xy, coverage_xy = pq_algorithm.calculate_gamut_coverage_DCIP3( xy_points ) reference_standard = "DCI-P3" self.log_gui.log(f"参考标准: {reference_standard}", level="success") self.log_gui.log(f"XY 色域覆盖率: {coverage_xy:.1f}%", level="success") # ========== ✅✅8. 重新计算 UV 色域覆盖率 ========== # 将 XY 坐标转换为 UV 坐标 uv_points = [] for x, y in xy_points: try: # XY转UV公式 denom = -2 * x + 12 * y + 3 if abs(denom) < 1e-10: u, v = 0, 0 else: u = 4 * x / denom v = 9 * y / denom uv_points.append([u, v]) except ZeroDivisionError: continue self.log_gui.log(f"转换后的 UV 点数量: {len(uv_points)}", level="success") # 根据参考标准计算 UV 覆盖率 if reference_standard == "BT.2020": area_uv, coverage_uv = pq_algorithm.calculate_gamut_coverage_BT2020_uv( uv_points ) elif reference_standard == "BT.709": area_uv, coverage_uv = pq_algorithm.calculate_gamut_coverage_BT709_uv( uv_points ) elif reference_standard == "DCI-P3": area_uv, coverage_uv = pq_algorithm.calculate_gamut_coverage_DCIP3_uv( uv_points ) else: area_uv, coverage_uv = pq_algorithm.calculate_gamut_coverage_DCIP3_uv( uv_points ) self.log_gui.log(f"UV 色域覆盖率: {coverage_uv:.1f}%", level="success") # ======================================================== # 9. 更新结果(同时保存 XY 和 UV 覆盖率) self.results.set_test_item_result( "gamut", { "area": area_xy, # ← 兼容旧字段 "coverage": coverage_xy, # ← 兼容旧字段 "area_xy": area_xy, # ← XY 面积 "coverage_xy": coverage_xy, # ← XY 覆盖率 "area_uv": area_uv, # ← UV 面积 "coverage_uv": coverage_uv, # ← UV 覆盖率 "uv_coverage": coverage_uv, # ← 兼容字段(Excel 导出用) "reference": reference_standard, }, ) self.log_gui.log("测试结果已更新到 results 对象", level="success") # 10. 重新绘制色域图 self.plot_gamut(rgb_data, coverage_xy, test_type) self.log_gui.log("色域图已重新绘制", level="success") self.log_gui.log("=" * 50, level="separator") messagebox.showinfo( "成功", f"色域图已根据新参考标准 {reference_standard} 重新绘制!\n\n" f"XY 覆盖率: {coverage_xy:.1f}%\n" f"UV 覆盖率: {coverage_uv:.1f}%", ) except Exception as e: self.log_gui.log(f"重新计算失败: {str(e)}", level="error") self.log_gui.log(traceback.format_exc(), level="error") messagebox.showerror("错误", f"重新计算失败: {str(e)}") def on_cct_param_focus_out(self, var, default_value): """色度参数失去焦点时的处理 - 空值恢复默认""" _handle_cct_focus_out(var, default_value, self.save_cct_params, "屏模组") def save_cct_params(self): """保存色度参数 - 简化版""" _save_cct_params_for(self.config.current_test_type) def reload_cct_params(self): """切换测试类型时重新加载色度参数""" try: current_type = self.config.current_test_type saved_params = self.config.current_test_types.get(current_type, {}).get( "cct_params", None ) if saved_params is None: saved_params = self.config.get_default_cct_params(current_type) # 更新输入框的值 self.cct_x_ideal_var.set(str(saved_params["x_ideal"])) self.cct_x_tolerance_var.set(str(saved_params["x_tolerance"])) self.cct_y_ideal_var.set(str(saved_params["y_ideal"])) self.cct_y_tolerance_var.set(str(saved_params["y_tolerance"])) except Exception as e: if hasattr(self, "log_gui"): self.log_gui.log(f"重新加载色度参数失败: {str(e)}", level="error") def toggle_cct_params_frame(self): """根据测试类型和测试项的选中状态显示对应参数框""" selected_items = self.get_selected_test_items() current_test_type = self.config.current_test_type # ========== 默认隐藏所有参数框 ========== self.cct_params_frame.pack_forget() self.sdr_cct_params_frame.pack_forget() # HDR 色度参数框(如果存在的话) if hasattr(self, "hdr_cct_params_frame"): self.hdr_cct_params_frame.pack_forget() # ========== 根据测试类型和选中项显示对应参数框 ========== if current_test_type == "screen_module": # 屏模组:只有色度参数 if "cct" in selected_items: self.cct_params_frame.pack(fill=tk.X, padx=5, pady=5) elif current_test_type == "sdr_movie": # SDR:只有色度参数(色准不需要参数设置框) if "cct" in selected_items: self.sdr_cct_params_frame.pack(fill=tk.X, padx=5, pady=5) elif current_test_type == "hdr_movie": # HDR:只有色度参数(色准不需要参数设置框) if "cct" in selected_items: if hasattr(self, "hdr_cct_params_frame"): self.hdr_cct_params_frame.pack(fill=tk.X, padx=5, pady=5) else: if hasattr(self, "log_gui"): self.log_gui.log("HDR 色度参数框尚未创建", level="error") # ---- gamut 参考标准改变回调(统一实现) ---- _GAMUT_REF_CONFIGS = { "screen_module": {"var_attr": "screen_gamut_ref_var", "label": "屏模组"}, "sdr_movie": {"var_attr": "sdr_gamut_ref_var", "label": "SDR"}, "hdr_movie": {"var_attr": "hdr_gamut_ref_var", "label": "HDR"}, } def _on_gamut_ref_changed(self, test_type, event=None): cfg = _GAMUT_REF_CONFIGS[test_type] try: new_ref = getattr(self, cfg["var_attr"]).get() self.log_gui.log(f"{cfg['label']} 色域参考标准已更改为: {new_ref}", level="success") if test_type not in self.config.current_test_types: self.config.current_test_types[test_type] = {} self.config.current_test_types[test_type]["gamut_reference"] = new_ref self.save_pq_config() except Exception as e: self.log_gui.log(f"保存 {cfg['label']} 色域参考标准失败: {str(e)}", level="error") def on_screen_gamut_ref_changed(self, event=None): _on_gamut_ref_changed(self, "screen_module", event) def on_sdr_gamut_ref_changed(self, event=None): _on_gamut_ref_changed(self, "sdr_movie", event) def on_hdr_gamut_ref_changed(self, event=None): _on_gamut_ref_changed(self, "hdr_movie", event)