Files
pqAutomationApp/app/views/panels/cct_panel.py
2026-04-20 16:44:46 +08:00

844 lines
29 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.
"""CCT 参数面板及其处理函数Step 6 重构)。"""
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="色度参数设置(屏模组)"
)
# 默认值
self.DEFAULT_CCT_PARAMS = {
"x_ideal": 0.3127,
"x_tolerance": 0.003,
"y_ideal": 0.3290,
"y_tolerance": 0.003,
}
# 从配置读取屏模组参数
saved_params = self.config.current_test_types.get("screen_module", {}).get(
"cct_params", self.DEFAULT_CCT_PARAMS.copy()
)
# 色域参考标准
saved_gamut_ref = self.config.current_test_types.get("screen_module", {}).get(
"gamut_reference", "DCI-P3"
)
# 创建屏模组变量
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 = self.DEFAULT_CCT_PARAMS[key]
entry.bind(
"<FocusOut>",
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(
"<<ComboboxSelected>>", 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 默认值
self.SDR_DEFAULT_CCT_PARAMS = {
"x_ideal": 0.3127,
"x_tolerance": 0.003,
"y_ideal": 0.3290,
"y_tolerance": 0.003,
}
# 从配置读取 SDR 参数
sdr_saved_params = self.config.current_test_types.get("sdr_movie", {}).get(
"cct_params", self.SDR_DEFAULT_CCT_PARAMS.copy()
)
# 色域参考标准
sdr_saved_gamut_ref = self.config.current_test_types.get("sdr_movie", {}).get(
"gamut_reference", "BT.709"
)
# 创建 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 = self.SDR_DEFAULT_CCT_PARAMS[key]
entry.bind(
"<FocusOut>",
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("<<ComboboxSelected>>", 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 默认值
self.HDR_DEFAULT_CCT_PARAMS = {
"x_ideal": 0.3127,
"x_tolerance": 0.003,
"y_ideal": 0.3290,
"y_tolerance": 0.003,
}
# 从配置读取 HDR 参数
hdr_saved_params = self.config.current_test_types.get("hdr_movie", {}).get(
"cct_params", self.HDR_DEFAULT_CCT_PARAMS.copy()
)
# 色域参考标准
hdr_saved_gamut_ref = self.config.current_test_types.get("hdr_movie", {}).get(
"gamut_reference", "BT.2020"
)
# 创建 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 = self.HDR_DEFAULT_CCT_PARAMS[key]
entry.bind(
"<FocusOut>",
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("<<ComboboxSelected>>", 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 on_sdr_cct_param_focus_out(self, var, default_value):
"""SDR 色度参数失去焦点时的处理"""
try:
value = var.get().strip()
if value == "":
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"✓ SDR 参数为空,恢复默认值: {default_value}")
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"⚠️ SDR 参数超出范围,恢复默认值: {default_value}"
)
except ValueError:
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"⚠️ SDR 参数无效,恢复默认值: {default_value}")
self.save_sdr_cct_params()
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"处理 SDR 参数失败: {str(e)}")
def save_sdr_cct_params(self):
"""保存 SDR 色度参数"""
try:
def get_float(var, default):
try:
value = var.get().strip()
if value == "":
return default
return float(value)
except:
return default
sdr_cct_params = {
"x_ideal": get_float(
self.sdr_cct_x_ideal_var, self.SDR_DEFAULT_CCT_PARAMS["x_ideal"]
),
"x_tolerance": get_float(
self.sdr_cct_x_tolerance_var,
self.SDR_DEFAULT_CCT_PARAMS["x_tolerance"],
),
"y_ideal": get_float(
self.sdr_cct_y_ideal_var, self.SDR_DEFAULT_CCT_PARAMS["y_ideal"]
),
"y_tolerance": get_float(
self.sdr_cct_y_tolerance_var,
self.SDR_DEFAULT_CCT_PARAMS["y_tolerance"],
),
}
if "sdr_movie" not in self.config.current_test_types:
self.config.current_test_types["sdr_movie"] = {}
self.config.current_test_types["sdr_movie"]["cct_params"] = sdr_cct_params
self.save_pq_config()
except:
pass
def on_hdr_cct_param_focus_out(self, var, default_value):
"""HDR 色度参数失去焦点时的处理"""
try:
value = var.get().strip()
if value == "":
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"✓ HDR 参数为空,恢复默认值: {default_value}")
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"⚠️ HDR 参数超出范围,恢复默认值: {default_value}"
)
except ValueError:
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"⚠️ HDR 参数无效,恢复默认值: {default_value}")
self.save_hdr_cct_params()
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"处理 HDR 参数失败: {str(e)}")
def save_hdr_cct_params(self):
"""保存 HDR 色度参数"""
try:
def get_float(var, default):
try:
value = var.get().strip()
if value == "":
return default
return float(value)
except:
return default
hdr_cct_params = {
"x_ideal": get_float(
self.hdr_cct_x_ideal_var, self.HDR_DEFAULT_CCT_PARAMS["x_ideal"]
),
"x_tolerance": get_float(
self.hdr_cct_x_tolerance_var,
self.HDR_DEFAULT_CCT_PARAMS["x_tolerance"],
),
"y_ideal": get_float(
self.hdr_cct_y_ideal_var, self.HDR_DEFAULT_CCT_PARAMS["y_ideal"]
),
"y_tolerance": get_float(
self.hdr_cct_y_tolerance_var,
self.HDR_DEFAULT_CCT_PARAMS["y_tolerance"],
),
}
if "hdr_movie" not in self.config.current_test_types:
self.config.current_test_types["hdr_movie"] = {}
self.config.current_test_types["hdr_movie"]["cct_params"] = hdr_cct_params
self.save_pq_config()
except:
pass
def recalculate_cct(self):
"""重新计算并绘制色度图"""
try:
# 1. 保存新参数
self.save_cct_params()
self.log_gui.log("✓ 色度参数已更新")
# 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("⚠️ 没有测试数据,无法重新绘制")
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("⚠️ 没有可用的灰阶数据")
messagebox.showwarning("警告", "没有找到色度测试数据")
return
# 6. 重新计算 CCT
self.log_gui.log("=" * 50)
self.log_gui.log("开始重新计算色度一致性...")
self.log_gui.log("=" * 50)
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("✓ 色度图已重新绘制")
self.log_gui.log("=" * 50)
messagebox.showinfo("成功", "色度图已根据新参数重新绘制!")
except Exception as e:
self.log_gui.log(f"❌ 重新计算失败: {str(e)}")
self.log_gui.log(traceback.format_exc())
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("⚠️ 没有测试数据,无法重新绘制")
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("⚠️ 没有可用的色域数据")
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)
self.log_gui.log(f"开始重新计算色域(参考标准: {reference_standard}...")
self.log_gui.log("=" * 50)
# 7. 重新计算 XY 色域覆盖率
xy_points = [[result[0], result[1]] for result in rgb_data]
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}")
self.log_gui.log(f"✓ XY 色域覆盖率: {coverage_xy:.1f}%")
# 8. 重新计算 UV 色域覆盖率
uv_points = []
for x, y in xy_points:
try:
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)}")
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}%")
# 9. 更新结果
self.results.set_test_item_result(
"gamut",
{
"area": area_xy,
"coverage": coverage_xy,
"area_xy": area_xy,
"coverage_xy": coverage_xy,
"area_uv": area_uv,
"coverage_uv": coverage_uv,
"uv_coverage": coverage_uv,
"reference": reference_standard,
},
)
self.log_gui.log("✓ 测试结果已更新到 results 对象")
# 10. 重新绘制色域图
self.plot_gamut(rgb_data, coverage_xy, test_type)
self.log_gui.log("✓ 色域图已重新绘制")
self.log_gui.log("=" * 50)
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)}")
self.log_gui.log(traceback.format_exc())
messagebox.showerror("错误", f"重新计算失败: {str(e)}")
def on_cct_param_change(self, var, default_value):
"""色度参数改变时的处理 - 空值恢复默认"""
try:
value = var.get().strip()
if value == "":
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"输入框为空,恢复默认值: {default_value}")
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"参数超出范围 [0, 1],恢复默认值: {default_value}"
)
except ValueError:
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"无效的参数值,恢复默认值: {default_value}")
self.save_cct_params()
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"处理参数变化失败: {str(e)}")
def on_cct_param_focus_out(self, var, default_value):
"""色度参数失去焦点时的处理 - 空值恢复默认"""
try:
value = var.get().strip()
if value == "":
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"✓ 输入框为空,恢复默认值: {default_value}")
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"⚠️ 参数超出范围 [0, 1],恢复默认值: {default_value}"
)
except ValueError:
var.set(str(default_value))
if hasattr(self, "log_gui"):
self.log_gui.log(f"⚠️ 无效的参数值,恢复默认值: {default_value}")
self.save_cct_params()
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"处理参数变化失败: {str(e)}")
def save_cct_params(self):
"""保存色度参数 - 简化版"""
try:
current_type = self.config.current_test_type
def get_float(var, default):
try:
value = var.get().strip()
if value == "":
return default
return float(value)
except:
return default
cct_params = {
"x_ideal": get_float(
self.cct_x_ideal_var, self.DEFAULT_CCT_PARAMS["x_ideal"]
),
"x_tolerance": get_float(
self.cct_x_tolerance_var, self.DEFAULT_CCT_PARAMS["x_tolerance"]
),
"y_ideal": get_float(
self.cct_y_ideal_var, self.DEFAULT_CCT_PARAMS["y_ideal"]
),
"y_tolerance": get_float(
self.cct_y_tolerance_var, self.DEFAULT_CCT_PARAMS["y_tolerance"]
),
}
if current_type not in self.config.current_test_types:
self.config.current_test_types[current_type] = {}
self.config.current_test_types[current_type]["cct_params"] = cct_params
self.save_pq_config()
except:
pass
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.DEFAULT_CCT_PARAMS.copy()
# 更新输入框的值
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)}")