添加信号格式修改
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
@@ -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]"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"])
|
||||
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
@@ -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):
|
||||
"""根据当前测试类型更新测试项目复选框"""
|
||||
# 先隐藏所有测试项目框架
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user