添加信号格式修改

This commit is contained in:
xinzhu.yin
2026-05-22 11:31:36 +08:00
parent c42287b7d7
commit 9b2bc44e17
14 changed files with 434 additions and 356 deletions

View File

@@ -49,6 +49,7 @@ def plot_accuracy(self, accuracy_data, test_type):
fontsize=11,
y=0.98,
fontweight="bold",
color="#111111",
)
# ========== 29色6行5列布局 ==========
@@ -205,6 +206,7 @@ def plot_accuracy(self, accuracy_data, test_type):
va="top",
fontsize=7.5,
fontweight="bold",
color="#111111",
transform=self.accuracy_ax.transAxes,
)
@@ -228,6 +230,7 @@ def plot_accuracy(self, accuracy_data, test_type):
va="center",
fontsize=7,
fontweight="bold",
color="#111111",
transform=self.accuracy_ax.transAxes,
)
@@ -279,11 +282,11 @@ def plot_accuracy(self, accuracy_data, test_type):
grade_color = "darkgreen"
elif avg_delta_e < 3:
grade = "优秀"
grade_icon = "✓✓"
grade_icon = "OK"
grade_color = "green"
elif avg_delta_e < 5:
grade = "良好"
grade_icon = ""
grade_icon = "PASS"
grade_color = "orange"
else:
grade = "需要校准"
@@ -298,6 +301,7 @@ def plot_accuracy(self, accuracy_data, test_type):
va="bottom",
fontsize=7,
fontweight="bold",
color="#111111",
transform=self.accuracy_ax.transAxes,
)

View File

@@ -143,12 +143,10 @@ def run_custom_sdr_test(self, test_items):
self.log_gui.log("执行客户定制 SDR 测试...", level="info")
# 获取信号格式设置
color_space = self.sdr_color_space_var.get() # BT.709/BT.601/BT.2020
gamma_type = self.sdr_gamma_type_var.get() # 2.2/2.4/2.6
data_range = self.sdr_data_range_var.get() # Full/Limited
bit_depth = self.sdr_bit_depth_var.get() # 8bit/10bit/12bit
self.log_gui.log(f"信号格式: 色彩空间={color_space}, Gamma={gamma_type}", level="info")
self.log_gui.log(f" 数据范围={data_range}, 编码位深={bit_depth}", level="info")
self.log_gui.log(f"信号格式: 色彩空间={color_space}, 数据范围={data_range}, 编码位深={bit_depth}", level="info")
self.log_gui.log("开始统一采集灰阶数据(用于 Gamma/CCT/对比度测试)", level="info")
self.test_custom_sdr()
@@ -168,12 +166,10 @@ def run_sdr_movie_test(self, test_items):
# 获取信号格式设置
color_space = self.sdr_color_space_var.get() # BT.709/BT.601/BT.2020
gamma_type = self.sdr_gamma_type_var.get() # 2.2/2.4/2.6
data_range = self.sdr_data_range_var.get() # Full/Limited
bit_depth = self.sdr_bit_depth_var.get() # 8bit/10bit/12bit
self.log_gui.log(f"信号格式: 色彩空间={color_space}, Gamma={gamma_type}", level="info")
self.log_gui.log(f" 数据范围={data_range}, 编码位深={bit_depth}", level="info")
self.log_gui.log(f"信号格式: 色彩空间={color_space}, 数据范围={data_range}, 编码位深={bit_depth}", level="info")
# 判断是否需要灰阶数据
needs_gray_data = any(
@@ -313,7 +309,20 @@ def send_fix_pattern(self, mode):
self.log_gui.log("=" * 50, level="separator")
# 4. 循环发送图案并采集数据
# 信号格式设置后等待电视重新锁定 HDMI 信号
# format_changed=True 表示本次 set_video_mode 的参数与上次不同TV 需要重新锁定
format_changed = getattr(getattr(self, "ucd", None), "format_changed", True)
if format_changed:
signal_settle = max(1.0, float(getattr(self, "signal_settle_time", 5.0)))
self.log_gui.log(
f"信号格式已变化,等待电视重新锁定: {signal_settle:.1f}s可通过 signal_settle_time 调整)",
level="info",
)
else:
signal_settle = 0.5
self.log_gui.log("信号格式未变化,短暂等待: 0.5s", level="info")
time.sleep(signal_settle)
total_patterns = session.total_patterns
self.log_gui.log(f"开始采集数据,共 {total_patterns} 个图案", level="info")
settle_time = max(0.2, float(getattr(self, "pattern_settle_time", 1.0)))
@@ -332,7 +341,8 @@ def send_fix_pattern(self, mode):
return results
should_log_detail = (
i == 0
total_patterns <= progress_step
or i == 0
or (i + 1) == total_patterns
or ((i + 1) % progress_step == 0)
)
@@ -477,12 +487,14 @@ def test_gamut(self, test_type):
# SDR 测试:使用色彩空间设置
color_space = self.sdr_color_space_var.get()
if color_space == "BT.709":
if color_space in ("sRGB", "BT.709"):
reference_standard = "BT.709"
elif color_space == "BT.601":
reference_standard = "BT.601"
elif color_space == "BT.2020":
reference_standard = "BT.2020"
elif color_space == "DCI-P3":
reference_standard = "DCI-P3"
else:
reference_standard = "BT.709"
self.log_gui.log(
@@ -665,7 +677,7 @@ def test_gamma(self, test_type, gray_data=None):
"gamma", {"gamma": results_with_gamma_list, "L_bar": L_bar}
)
# 绘制Gamma曲线
# 绘制Gamma曲线SDR 使用用户选择的参考值)
if test_type == "sdr_movie":
try:
target_gamma = float(self.sdr_gamma_type_var.get())
@@ -673,7 +685,6 @@ def test_gamma(self, test_type, gray_data=None):
target_gamma = 2.2
else:
target_gamma = 2.2
self.plot_gamma(L_bar, results_with_gamma_list, target_gamma, test_type)
self._save_chart_snapshot(test_type, "gamma", (L_bar, results_with_gamma_list, target_gamma, test_type))
@@ -877,7 +888,7 @@ def test_contrast(self, test_type, gray_data=None):
def test_color_accuracy(self, test_type):
"""测试色准 - 使用手工实现的 ΔE 2000应用 Gamma"""
# ========== 读取用户选择的 Gamma ==========
# ========== Gamma 参考值 ==========
if test_type == "sdr_movie":
try:
target_gamma = float(self.sdr_gamma_type_var.get())
@@ -886,7 +897,7 @@ def test_color_accuracy(self, test_type):
self.log_gui.log("=" * 50, level="separator")
self.log_gui.log(f"开始测试色准SDR Movie 标准 - 29色", level="info")
self.log_gui.log(f"使用 Gamma: {target_gamma}", level="success") # ← 新增
self.log_gui.log(f"使用 Gamma: {target_gamma}", level="success")
self.log_gui.log("=" * 50, level="separator")
elif test_type == "hdr_movie":
@@ -962,9 +973,9 @@ def test_color_accuracy(self, test_type):
color_patches.append(name)
if delta_e < 3:
grade, icon = "优秀", ""
grade, icon = "优秀", "OK"
elif delta_e < 5:
grade, icon = "良好", ""
grade, icon = "良好", "WARN"
else:
grade, icon = "偏差", "[Error]"

View File

@@ -16,6 +16,7 @@ import json
import logging
import mimetypes
import os
import sys
import shutil
import threading
import time
@@ -253,8 +254,13 @@ def _call_pqtest_generate(user_message: str, session_id: str, timeout: float = A
def get_cache_dir(base_dir: Optional[str] = None) -> str:
"""返回缓存目录,如不存在则创建。``base_dir`` 默认使用当前工作目录。"""
root = base_dir if base_dir else os.getcwd()
"""返回缓存目录,如不存在则创建。``base_dir`` 留空时使用应用根目录。"""
if base_dir:
root = base_dir
elif getattr(sys, "frozen", False):
root = os.path.dirname(sys.executable)
else:
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
path = os.path.join(root, _CACHE_DIRNAME)
os.makedirs(path, exist_ok=True)
return path

View File

@@ -40,56 +40,72 @@ class PatternService:
"info",
)
self.app.ucd.set_ucd_params(active_config)
elif test_type == "sdr_movie":
active_config = self._prepare_video_session(
mode=mode,
test_type=test_type,
source_params=source_params,
data_range=self.app.sdr_data_range_var.get(),
log_title="设置 SDR 信号格式:",
setup_message=f"设置 SDR 测试图案({mode} 模式)..."
if mode != "accuracy"
else "设置 SDR 29色色准测试图案...",
setup_format=lambda: self.app.ucd.set_sdr_format(
color_space=self.app.sdr_color_space_var.get(),
gamma=self.app.sdr_gamma_type_var.get(),
data_range=self.app.sdr_data_range_var.get(),
bit_depth=self.app.sdr_bit_depth_var.get(),
),
log_items=[
data_range = self.app.sdr_data_range_var.get()
if log_details:
self._log("=" * 50, "separator")
self._log("设置 SDR 信号格式:", "info")
self._log("=" * 50, "separator")
for label, value in [
("色彩空间", self.app.sdr_color_space_var.get()),
("Gamma", self.app.sdr_gamma_type_var.get()),
("数据范围", self.app.sdr_data_range_var.get()),
("色彩格式", self.app.sdr_output_format_var.get()),
("Gamma", self.app.sdr_gamma_type_var.get()),
("数据范围", data_range),
("编码位深", self.app.sdr_bit_depth_var.get()),
],
log_details=log_details,
]:
self._log(f" {label}: {value}", "info")
converted_params = convert_pattern_params(
source_params, data_range=data_range, verbose=False
)
active_config = self.app.config.get_temp_config_with_converted_params(
mode=mode, converted_params=converted_params
)
self.app.ucd.set_ucd_params(active_config)
success = self.app.ucd.apply_signal_format(
color_space=self.app.sdr_color_space_var.get(),
data_range=data_range,
bit_depth=self.app.sdr_bit_depth_var.get(),
color_format=self.app.sdr_output_format_var.get(),
)
if log_details:
self._log(f"SDR 信号格式设置{'成功' if success else '失败'}", "success" if success else "error")
self._log(f"图案参数已设置,共 {len(converted_params)} 个图案", "success")
elif test_type == "hdr_movie":
active_config = self._prepare_video_session(
mode=mode,
test_type=test_type,
source_params=source_params,
data_range=self.app.hdr_data_range_var.get(),
log_title="设置 HDR 信号格式:",
setup_message=f"设置 HDR 测试图案({mode} 模式)..."
if mode != "accuracy"
else "设置 HDR 29色色准测试图案...",
setup_format=lambda: self.app.ucd.set_hdr_format(
color_space=self.app.hdr_color_space_var.get(),
data_range=self.app.hdr_data_range_var.get(),
bit_depth=self.app.hdr_bit_depth_var.get(),
max_cll=self.app.hdr_maxcll_var.get(),
max_fall=self.app.hdr_maxfall_var.get(),
),
log_items=[
data_range = self.app.hdr_data_range_var.get()
if log_details:
self._log("=" * 50, "separator")
self._log("设置 HDR 信号格式:", "info")
self._log("=" * 50, "separator")
for label, value in [
("色彩空间", self.app.hdr_color_space_var.get()),
("数据范围", self.app.hdr_data_range_var.get()),
("色彩格式", self.app.hdr_output_format_var.get()),
("数据范围", data_range),
("编码位深", self.app.hdr_bit_depth_var.get()),
("MaxCLL", self.app.hdr_maxcll_var.get()),
("MaxCLL", self.app.hdr_maxcll_var.get()),
("MaxFALL", self.app.hdr_maxfall_var.get()),
],
log_details=log_details,
]:
self._log(f" {label}: {value}", "info")
converted_params = convert_pattern_params(
source_params, data_range=data_range, verbose=False
)
active_config = self.app.config.get_temp_config_with_converted_params(
mode=mode, converted_params=converted_params
)
self.app.ucd.set_ucd_params(active_config)
success = self.app.ucd.apply_signal_format(
color_space=self.app.hdr_color_space_var.get(),
data_range=data_range,
bit_depth=self.app.hdr_bit_depth_var.get(),
color_format=self.app.hdr_output_format_var.get(),
max_cll=self.app.hdr_maxcll_var.get(),
max_fall=self.app.hdr_maxfall_var.get(),
)
if log_details:
self._log(f"HDR 信号格式设置{'成功' if success else '失败'}", "success" if success else "error")
self._log(f"图案参数已设置,共 {len(converted_params)} 个图案", "success")
else:
raise ValueError(f"不支持的测试类型: {test_type}")
@@ -122,50 +138,6 @@ class PatternService:
send_solid_rgb_pattern(self.app.ucd, converted_rgb, raise_on_error=True)
return True
def _prepare_video_session(
self,
*,
mode,
test_type,
source_params,
data_range,
log_title,
setup_message,
setup_format,
log_items,
log_details,
):
if log_details:
self._log("=" * 50, "separator")
self._log(log_title, "info")
self._log("=" * 50, "separator")
for label, value in log_items:
self._log(f" {label}: {value}", "info")
success = setup_format()
if log_details:
self._log(
f"{test_type.split('_')[0].upper()} 信号格式设置{'成功' if success else '失败'}",
"success" if success else "error",
)
self._log(setup_message, "info")
converted_params = convert_pattern_params(
pattern_params=source_params,
data_range=data_range,
verbose=False,
)
active_config = self.app.config.get_temp_config_with_converted_params(
mode=mode,
converted_params=converted_params,
)
self.app.ucd.set_ucd_params(active_config)
if log_details:
self._log(f"图案参数已设置,共 {len(converted_params)} 个图案", "success")
return active_config
def _get_source_pattern_params(self, mode):
return copy.deepcopy(get_pattern(mode)["pattern_params"])

View File

@@ -3,6 +3,7 @@
from __future__ import annotations
import os
import sys
import threading
import tkinter as tk
from tkinter import filedialog, messagebox, simpledialog
@@ -193,6 +194,15 @@ def toggle_ai_image_panel(self):
self.show_panel("ai_image")
def _get_app_base_dir(self) -> str:
"""返回应用根目录settings 的上一级)。"""
if getattr(self, "config_file", None):
return os.path.dirname(os.path.dirname(self.config_file))
if getattr(sys, "frozen", False):
return os.path.dirname(sys.executable)
return os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
# ---------------- 列表 / 选中 ----------------
@@ -203,7 +213,7 @@ def reload_ai_image_list(self, auto_select_first=True):
其下列出该轮生成的所有图片。会话按"最近使用"倒序,组内按时间倒序。
auto_select_first: 是否自动选中第一张图片(默认 True
"""
self.ai_image_records = _svc.list_records()
self.ai_image_records = _svc.list_records(base_dir=_get_app_base_dir(self))
self.ai_image_listbox.delete(0, tk.END)
# 维护行号 → 记录索引的映射;分隔头处为 None
self._ai_image_row_map = []
@@ -414,6 +424,7 @@ def _send_prompt(self):
prompt,
on_success=_success,
on_error=_error,
base_dir=_get_app_base_dir(self),
cancel_event=self._ai_image_cancel_event,
)
return
@@ -422,6 +433,7 @@ def _send_prompt(self):
prompt,
on_success=_success,
on_error=_error,
base_dir=_get_app_base_dir(self),
cancel_event=self._ai_image_cancel_event,
)

View File

@@ -137,21 +137,21 @@ def create_signal_format_content(self):
sdr_color_space_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_color_space_var,
values=["BT.709", "BT.601", "BT.2020"],
values=["sRGB", "BT.709", "BT.601", "BT.2020", "DCI-P3"],
width=10,
state="readonly",
)
sdr_color_space_combo.grid(row=0, column=1, sticky=tk.W, padx=5, pady=2)
# Gamma
# Gamma测试参考值用于Gamma曲线绘制和色准计算
ttk.Label(self.sdr_signal_frame, text="Gamma:").grid(
row=1, column=0, sticky=tk.W, padx=5, pady=2
)
self.sdr_gamma_type_var = tk.StringVar(value="2.2")
self.sdr_gamma_type_var = tk.StringVar(value=UCDEnum.SignalFormat.GammaType.GAMMA_22)
sdr_gamma_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_gamma_type_var,
values=["2.2", "2.4", "2.6"],
values=UCDEnum.SignalFormat.GammaType.get_list(),
width=10,
state="readonly",
)
@@ -161,11 +161,11 @@ def create_signal_format_content(self):
ttk.Label(self.sdr_signal_frame, text="数据范围:").grid(
row=2, column=0, sticky=tk.W, padx=5, pady=2
)
self.sdr_data_range_var = tk.StringVar(value="Full")
self.sdr_data_range_var = tk.StringVar(value=UCDEnum.SignalFormat.DataRange.FULL)
sdr_range_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_data_range_var,
values=["Full", "Limited"],
values=UCDEnum.SignalFormat.DataRange.get_list(),
width=10,
state="readonly",
)
@@ -175,16 +175,50 @@ def create_signal_format_content(self):
ttk.Label(self.sdr_signal_frame, text="编码位深:").grid(
row=3, column=0, sticky=tk.W, padx=5, pady=2
)
self.sdr_bit_depth_var = tk.StringVar(value="8bit")
self.sdr_bit_depth_var = tk.StringVar(value=UCDEnum.SignalFormat.BitDepth.BIT_8)
sdr_bit_depth_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_bit_depth_var,
values=["8bit", "10bit", "12bit"],
values=UCDEnum.SignalFormat.BitDepth.get_list(),
width=10,
state="readonly",
)
sdr_bit_depth_combo.grid(row=3, column=1, sticky=tk.W, padx=5, pady=2)
# 分辨率
ttk.Label(self.sdr_signal_frame, text="分辨率:").grid(
row=4, column=0, sticky=tk.W, padx=5, pady=2
)
self.sdr_timing_var = tk.StringVar(
value=self.config.current_test_types.get("sdr_movie", {}).get(
"timing", "DMT 1920x1080@60Hz"
)
)
sdr_timing_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_timing_var,
values=UCDEnum.TimingInfo.get_formatted_resolution_list(),
width=20,
state="readonly",
)
sdr_timing_combo.bind("<<ComboboxSelected>>", self.on_sdr_timing_changed)
sdr_timing_combo.grid(row=4, column=1, sticky=tk.W, padx=5, pady=2)
# 色彩格式
ttk.Label(self.sdr_signal_frame, text="色彩格式:").grid(
row=5, column=0, sticky=tk.W, padx=5, pady=2
)
self.sdr_output_format_var = tk.StringVar(value=UCDEnum.SignalFormat.OutputFormat.RGB)
sdr_output_format_combo = ttk.Combobox(
self.sdr_signal_frame,
textvariable=self.sdr_output_format_var,
values=UCDEnum.SignalFormat.OutputFormat.get_list(),
width=10,
state="readonly",
)
sdr_output_format_combo.bind("<<ComboboxSelected>>", self.on_sdr_output_format_changed)
sdr_output_format_combo.grid(row=5, column=1, sticky=tk.W, padx=5, pady=2)
# ==================== HDR信号格式设置 ====================
self.hdr_signal_frame = ttk.Frame(self.signal_tabs)
# 配置列权重
@@ -235,11 +269,11 @@ def create_signal_format_content(self):
ttk.Label(self.hdr_signal_frame, text="数据范围:").grid(
row=3, column=0, sticky=tk.W, padx=5, pady=2
)
self.hdr_data_range_var = tk.StringVar(value="Full")
self.hdr_data_range_var = tk.StringVar(value=UCDEnum.SignalFormat.DataRange.FULL)
hdr_range_combo = ttk.Combobox(
self.hdr_signal_frame,
textvariable=self.hdr_data_range_var,
values=["Full", "Limited"],
values=UCDEnum.SignalFormat.DataRange.get_list(),
width=10,
state="readonly",
)
@@ -249,16 +283,31 @@ def create_signal_format_content(self):
ttk.Label(self.hdr_signal_frame, text="编码位深:").grid(
row=4, column=0, sticky=tk.W, padx=5, pady=2
)
self.hdr_bit_depth_var = tk.StringVar(value="8bit")
self.hdr_bit_depth_var = tk.StringVar(value=UCDEnum.SignalFormat.BitDepth.BIT_8)
hdr_bit_depth_combo = ttk.Combobox(
self.hdr_signal_frame,
textvariable=self.hdr_bit_depth_var,
values=["8bit", "10bit", "12bit"],
values=UCDEnum.SignalFormat.BitDepth.get_list(),
width=10,
state="readonly",
)
hdr_bit_depth_combo.grid(row=4, column=1, sticky=tk.W, padx=5, pady=2)
# 色彩格式
ttk.Label(self.hdr_signal_frame, text="色彩格式:").grid(
row=5, column=0, sticky=tk.W, padx=5, pady=2
)
self.hdr_output_format_var = tk.StringVar(value=UCDEnum.SignalFormat.OutputFormat.RGB)
hdr_output_format_combo = ttk.Combobox(
self.hdr_signal_frame,
textvariable=self.hdr_output_format_var,
values=UCDEnum.SignalFormat.OutputFormat.get_list(),
width=10,
state="readonly",
)
hdr_output_format_combo.bind("<<ComboboxSelected>>", self.on_hdr_output_format_changed)
hdr_output_format_combo.grid(row=5, column=1, sticky=tk.W, padx=5, pady=2)
# ==================== 初始化:默认只启用屏模组 Tab ====================
self.signal_tabs.select(0) # 选中屏模组
self.signal_tabs.tab(1, state="disabled") # 禁用 SDR
@@ -271,8 +320,9 @@ def create_connection_content(self):
com_frame = ttk.Frame(self.connection_frame)
com_frame.pack(fill=tk.X, pady=5)
# 获取可用的COM端口列表
# 获取可用的COM端口列表和UCD设备列表
available_ports = self.get_available_com_ports()
available_ucd_list = self.get_available_ucd_ports()
# 使用网格布局,更整齐
ttk.Label(com_frame, text="UCD列表:").grid(
@@ -282,7 +332,7 @@ def create_connection_content(self):
self.ucd_list_combo = ttk.Combobox(
com_frame,
textvariable=self.ucd_list_var,
values=available_ports,
values=available_ucd_list,
width=10,
state="readonly",
)
@@ -453,6 +503,19 @@ def create_test_type_frame(self):
)
self.pantone_baseline_btn.pack(fill=tk.X, padx=0, pady=1)
# 测试版水印标签(版本 x.x.0.0 时显示)
from app_version import is_beta_version, APP_VERSION
if is_beta_version():
beta_lbl = tk.Label(
self.sidebar_frame,
text=f"[测试版] v{APP_VERSION}",
foreground="#ffffff",
background="#cc3300",
font=("微软雅黑", 8, "bold"),
anchor="center",
)
beta_lbl.pack(fill=tk.X, side=tk.BOTTOM, padx=4, pady=(6, 4))
# 注册面板按钮
if hasattr(self, "panels"):
if "log" in self.panels:
@@ -569,6 +632,74 @@ def on_screen_module_timing_changed(self, event=None):
self.log_gui.log(f"屏模组信号格式更改失败: {str(e)}", level="error")
def on_sdr_timing_changed(self, event=None):
"""SDR测试分辨率改变时的回调"""
try:
selected_timing = self.sdr_timing_var.get()
self.log_gui.log(f"SDR测试分辨率已更改为: {selected_timing}", level="info")
# 直接更新 sdr_movie 的 timing 配置
self.config.current_test_types["sdr_movie"]["timing"] = selected_timing
if self.testing:
self.log_gui.log("警告: 测试进行中,分辨率更改将在下次测试时生效", level="error")
self.save_pq_config()
except Exception as e:
self.log_gui.log(f"SDR测试分辨率更改失败: {str(e)}", level="error")
def on_sdr_output_format_changed(self, event=None):
"""SDR 色彩格式改变时的回调"""
try:
fmt = self.sdr_output_format_var.get()
self.log_gui.log(f"SDR色彩格式已更改为: {fmt}", level="info")
if self.testing:
self.log_gui.log("警告: 测试进行中,格式更改将在下次测试时生效", level="error")
return
if getattr(self.ucd, "status", False):
ok = self.ucd.apply_signal_format(
color_space=self.sdr_color_space_var.get(),
data_range=self.sdr_data_range_var.get(),
bit_depth=self.sdr_bit_depth_var.get(),
color_format=fmt,
)
if not ok:
self.log_gui.log("SDR色彩格式应用到UCD失败", level="error")
except Exception as e:
self.log_gui.log(f"SDR色彩格式更改失败: {str(e)}", level="error")
def on_hdr_output_format_changed(self, event=None):
"""HDR 色彩格式改变时的回调"""
try:
fmt = self.hdr_output_format_var.get()
self.log_gui.log(f"HDR色彩格式已更改为: {fmt}", level="info")
if self.testing:
self.log_gui.log("警告: 测试进行中,格式更改将在下次测试时生效", level="error")
return
if getattr(self.ucd, "status", False):
ok = self.ucd.apply_signal_format(
color_space=self.hdr_color_space_var.get(),
data_range=self.hdr_data_range_var.get(),
bit_depth=self.hdr_bit_depth_var.get(),
max_cll=self.hdr_maxcll_var.get(),
max_fall=self.hdr_maxfall_var.get(),
color_format=fmt,
)
if not ok:
self.log_gui.log("HDR色彩格式应用到UCD失败", level="error")
except Exception as e:
self.log_gui.log(f"HDR色彩格式更改失败: {str(e)}", level="error")
def update_test_items(self):
"""根据当前测试类型更新测试项目复选框"""
# 先隐藏所有测试项目框架

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
import datetime
import os
import sys
import threading
import tkinter as tk
from tkinter import filedialog, messagebox
@@ -11,7 +12,7 @@ from tkinter import filedialog, messagebox
import ttkbootstrap as ttk
_TEMPLATE_FILE = "pantone\xa02670\xa0colors.xlsx"
_TEMPLATE_FILE = "pantone_2670_colors.xlsx"
def create_pantone_baseline_panel(self):
@@ -153,8 +154,22 @@ def toggle_pantone_baseline_panel(self):
self.show_panel("pantone_baseline")
def _get_settings_dir(self):
"""返回 settings 绝对目录,避免依赖当前工作目录。"""
if getattr(self, "config_file", None):
return os.path.dirname(self.config_file)
if getattr(sys, "frozen", False):
base_dir = os.path.dirname(sys.executable)
else:
base_dir = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
)
return os.path.join(base_dir, "settings")
def _load_patterns(self):
path = os.path.join("settings", _TEMPLATE_FILE)
path = os.path.join(_get_settings_dir(self), _TEMPLATE_FILE)
if not os.path.isfile(path):
raise FileNotFoundError(f"未找到模板文件: {path}")
@@ -513,7 +528,7 @@ def _auto_save_template(self):
def _write_template_xlsx(self, path):
# 优先复制 settings 模板,再覆盖数据区;没有模板时自动创建同结构表。
template_path = os.path.join("settings", _TEMPLATE_FILE)
template_path = os.path.join(_get_settings_dir(self), _TEMPLATE_FILE)
from openpyxl import load_workbook, Workbook
if os.path.isfile(template_path):