修改AI生图接口、修改设备连接UI、修改LocalDimming逻辑和UI

This commit is contained in:
xinzhu.yin
2026-05-29 14:40:39 +08:00
parent 21455f3916
commit 85ac47e8de
13 changed files with 811 additions and 304 deletions

View File

@@ -36,13 +36,7 @@ def _make_card(parent, icon: str, title: str) -> ttk.Frame:
def create_floating_config_panel(self: "PQAutomationApp"):
"""创建顶部"配置项"现代化折叠面板
布局变化vs 旧版):
- 用 Unicode chevron + 整条 header 可点击折叠/展开;
- header 上额外显示折叠状态预览(``config_preview_var``
- header 右侧承载常驻操作工具条(开始/停止/保存 等),不再放中部;
- 内部三个区段从 LabelFrame 改为统一的 Card 样式。
"""创建顶部"配置项"现代化折叠面板
"""
cf = CollapsingFrame(self.control_frame_top)
cf.pack(fill="both")
@@ -54,8 +48,7 @@ def create_floating_config_panel(self: "PQAutomationApp"):
# 折叠预览:呈现"测试类型 · 已选测试项"
self.config_preview_var = tk.StringVar(value="")
# header 右侧工具条占位 —— create_operation_frame 之后向这里挂按钮
self.toolbar_actions_frame: ttk.Frame | None = None
self.toolbar_actions_frame = None
def _header_actions(parent: ttk.Frame):
# 暴露给 create_operation_frame 使用
@@ -90,7 +83,7 @@ def create_floating_config_panel(self: "PQAutomationApp"):
signal_card.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(6, 0))
self.signal_format_frame = signal_card._body # type: ignore[attr-defined]
# 创建卡片内部内容(沿用旧函数,父级已是 body Frame
# 创建卡片内部内容
self.create_connection_content()
self.create_test_items_content()
self.create_signal_format_content()
@@ -111,6 +104,7 @@ def refresh_config_preview(self: "PQAutomationApp") -> None:
"screen_module": "屏模组",
"sdr_movie": "SDR Movie",
"hdr_movie": "HDR Movie",
"local_dimming": "Local Dimming",
}
current_type = getattr(self.config, "current_test_type", "")
type_label = type_labels.get(current_type, "")
@@ -171,6 +165,10 @@ def create_test_items_content(self: "PQAutomationApp"):
("色准", "accuracy"),
],
},
"local_dimming": {
"frame": ttk.Frame(self.test_items_frame),
"items": [],
},
}
# 根据当前测试类型创建复选框
@@ -473,10 +471,103 @@ def create_signal_format_content(self: "PQAutomationApp"):
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)
# ==================== Local Dimming 信号格式设置 ====================
self.local_dimming_signal_frame = ttk.Frame(self.signal_tabs)
self.local_dimming_signal_frame.grid_columnconfigure(0, weight=0)
self.local_dimming_signal_frame.grid_columnconfigure(1, weight=1)
self.signal_tabs.add(self.local_dimming_signal_frame, text="Local Dimming")
ld_cfg = self.config.current_test_types.get("local_dimming", {})
ttk.Label(self.local_dimming_signal_frame, text="分辨率:").grid(
row=0, column=0, sticky=tk.W, padx=5, pady=2
)
self.local_dimming_timing_var = tk.StringVar(
value=ld_cfg.get("timing", "DMT 1920x 1080 @ 60Hz")
)
ld_timing_combo = ttk.Combobox(
self.local_dimming_signal_frame,
textvariable=self.local_dimming_timing_var,
values=UCDEnum.TimingInfo.get_formatted_resolution_list(),
width=20,
state="readonly",
)
ld_timing_combo.bind("<<ComboboxSelected>>", self.on_local_dimming_timing_changed)
ld_timing_combo.grid(row=0, column=1, sticky=tk.W, padx=5, pady=2)
ttk.Label(self.local_dimming_signal_frame, text="色彩空间:").grid(
row=1, column=0, sticky=tk.W, padx=5, pady=2
)
self.local_dimming_color_space_var = tk.StringVar(
value=ld_cfg.get("colorimetry", "sRGB")
)
ld_color_space_combo = ttk.Combobox(
self.local_dimming_signal_frame,
textvariable=self.local_dimming_color_space_var,
values=["sRGB", "BT.709", "BT.601", "BT.2020", "DCI-P3"],
width=10,
state="readonly",
)
ld_color_space_combo.bind("<<ComboboxSelected>>", self.on_local_dimming_signal_format_changed)
ld_color_space_combo.grid(row=1, column=1, sticky=tk.W, padx=5, pady=2)
ttk.Label(self.local_dimming_signal_frame, text="数据范围:").grid(
row=2, column=0, sticky=tk.W, padx=5, pady=2
)
self.local_dimming_data_range_var = tk.StringVar(
value=ld_cfg.get("data_range", UCDEnum.SignalFormat.DataRange.FULL)
)
ld_data_range_combo = ttk.Combobox(
self.local_dimming_signal_frame,
textvariable=self.local_dimming_data_range_var,
values=UCDEnum.SignalFormat.DataRange.get_list(),
width=10,
state="readonly",
)
ld_data_range_combo.bind("<<ComboboxSelected>>", self.on_local_dimming_signal_format_changed)
ld_data_range_combo.grid(row=2, column=1, sticky=tk.W, padx=5, pady=2)
default_ld_bpc = int(ld_cfg.get("bpc", 8))
default_ld_bit_depth = (
f"{default_ld_bpc}bit"
if f"{default_ld_bpc}bit" in UCDEnum.SignalFormat.BitDepth.get_list()
else UCDEnum.SignalFormat.BitDepth.BIT_8
)
ttk.Label(self.local_dimming_signal_frame, text="编码位深:").grid(
row=3, column=0, sticky=tk.W, padx=5, pady=2
)
self.local_dimming_bit_depth_var = tk.StringVar(value=default_ld_bit_depth)
ld_bit_depth_combo = ttk.Combobox(
self.local_dimming_signal_frame,
textvariable=self.local_dimming_bit_depth_var,
values=UCDEnum.SignalFormat.BitDepth.get_list(),
width=10,
state="readonly",
)
ld_bit_depth_combo.bind("<<ComboboxSelected>>", self.on_local_dimming_signal_format_changed)
ld_bit_depth_combo.grid(row=3, column=1, sticky=tk.W, padx=5, pady=2)
ttk.Label(self.local_dimming_signal_frame, text="色彩格式:").grid(
row=4, column=0, sticky=tk.W, padx=5, pady=2
)
self.local_dimming_output_format_var = tk.StringVar(
value=ld_cfg.get("color_format", UCDEnum.SignalFormat.OutputFormat.RGB)
)
ld_output_format_combo = ttk.Combobox(
self.local_dimming_signal_frame,
textvariable=self.local_dimming_output_format_var,
values=UCDEnum.SignalFormat.OutputFormat.get_list(),
width=10,
state="readonly",
)
ld_output_format_combo.bind("<<ComboboxSelected>>", self.on_local_dimming_signal_format_changed)
ld_output_format_combo.grid(row=4, column=1, sticky=tk.W, padx=5, pady=2)
# ==================== 初始化:默认只启用屏模组 Tab ====================
self.signal_tabs.select(0) # 选中屏模组
self.signal_tabs.tab(1, state="disabled") # 禁用 SDR
self.signal_tabs.tab(2, state="disabled") # 禁用 HDR
self.signal_tabs.tab(3, state="disabled") # 禁用 Local Dimming
def create_connection_content(self: "PQAutomationApp"):
@@ -513,41 +604,50 @@ def create_connection_content(self: "PQAutomationApp"):
# 添加按钮框架
button_frame = ttk.Frame(com_frame)
button_frame.grid(row=3, column=0, columnspan=3, pady=3, sticky="w")
button_frame.grid(row=3, column=0, columnspan=3, pady=3, sticky="ew")
button_frame.grid_columnconfigure(0, weight=1)
button_frame.grid_columnconfigure(1, weight=1)
button_frame.grid_columnconfigure(2, weight=1)
connect_icon = load_icon("assets/connect-svgrepo-com.png")
# connect_icon = load_icon("assets/connect-svgrepo-com.png")
self.check_button = ttk.Button(
button_frame,
image=connect_icon,
bootstyle="link",
# image=connect_icon,
# bootstyle="link",
text="连接",
bootstyle="success",
takefocus=False,
command=self.check_com_connections,
)
self.check_button.image = connect_icon
self.check_button.pack(side="left", padx=0, pady=3)
# self.check_button.image = connect_icon
self.check_button.grid(row=0, column=0, padx=(0, 4), pady=3, sticky="ew")
disconnect_icon = load_icon("assets/disconnect-svgrepo-com.png")
# disconnect_icon = load_icon("assets/disconnect-svgrepo-com.png")
# 断开连接按钮
self.disconnect_button = ttk.Button(
button_frame,
image=disconnect_icon,
bootstyle="link",
# image=disconnect_icon,
# bootstyle="link",
text="断开",
bootstyle="danger",
takefocus=False,
command=self.disconnect_com_connections,
)
self.disconnect_button.image = disconnect_icon # 防止图标被垃圾回收
self.disconnect_button.pack(side="left", padx=0, pady=3)
# self.disconnect_button.image = disconnect_icon # 防止图标被垃圾回收
self.disconnect_button.grid(row=0, column=1, padx=4, pady=3, sticky="ew")
refresh_icon = load_icon("assets/refresh-svgrepo-com.png")
# refresh_icon = load_icon("assets/refresh-svgrepo-com.png")
self.refresh_button = ttk.Button(
button_frame,
image=refresh_icon,
bootstyle="link",
# image=refresh_icon,
# bootstyle="link",
text="刷新",
bootstyle="info",
takefocus=False,
command=self.refresh_com_ports,
)
self.refresh_button.image = refresh_icon # 防止图标被垃圾回收
self.refresh_button.pack(side="left", padx=0, pady=3)
# self.refresh_button.image = refresh_icon # 防止图标被垃圾回收
self.refresh_button.grid(row=0, column=2, padx=(4, 0), pady=3, sticky="ew")
# CA端口
ttk.Label(com_frame, text="CA端口:").grid(
@@ -591,12 +691,6 @@ def create_connection_content(self: "PQAutomationApp"):
def create_test_type_frame(self: "PQAutomationApp"):
"""创建测试类型选择区域(侧边栏形式)。
新版v3改进
- 深灰分层背景,接近 Calman 的侧栏密度;
- 纯文字按钮,不使用 emoji
- 用更克制的字号 / 间距做层级区分;
- 不再使用 padding=10 硬覆盖(交给 Sidebar.TButton 样式统一管理)。
"""
# 设置测试类型变量
self.test_type_var = tk.StringVar(value="screen_module")
@@ -621,6 +715,7 @@ def create_test_type_frame(self: "PQAutomationApp"):
("屏模组性能测试", "screen_module"),
("SDR Movie", "sdr_movie"),
("HDR Movie", "hdr_movie"),
("Local Dimming", "local_dimming"),
]
for text, type_value in test_types:
@@ -643,7 +738,6 @@ def create_test_type_frame(self: "PQAutomationApp"):
panel_buttons = [
("log_btn", "测试日志", self.toggle_log_panel),
("local_dimming_btn", "Local Dimming", self.toggle_local_dimming_panel),
("ai_image_btn", "AI 图片", self.toggle_ai_image_panel),
("pantone_baseline_btn", "Pantone 摸底", self.toggle_pantone_baseline_panel),
("gamma_pattern_btn", "Gamma 图案", self.toggle_gamma_pattern_panel),
@@ -688,8 +782,6 @@ def create_test_type_frame(self: "PQAutomationApp"):
if hasattr(self, "panels"):
if "log" in self.panels:
self.panels["log"]["button"] = self.log_btn
if "local_dimming" in self.panels:
self.panels["local_dimming"]["button"] = self.local_dimming_btn
if "ai_image" in self.panels:
self.panels["ai_image"]["button"] = self.ai_image_btn
if "single_step" in self.panels:
@@ -785,16 +877,6 @@ def create_operation_frame(self: "PQAutomationApp"):
)
self.start_btn.pack(side=tk.LEFT, **btn_pad)
self.simulate_btn = ttk.Button(
parent,
text="模拟测试",
command=self.run_simulation_test,
bootstyle="warning-outline",
padding=(12, 6),
takefocus=False,
)
self.simulate_btn.pack(side=tk.LEFT, **btn_pad)
self.stop_btn = ttk.Button(
parent,
text="\u25a0 停止",
@@ -995,6 +1077,65 @@ def on_hdr_output_format_changed(self: "PQAutomationApp", event=None):
self.log_gui.log(f"HDR色彩格式更改失败: {str(e)}", level="error")
def on_local_dimming_timing_changed(self: "PQAutomationApp", event=None):
"""Local Dimming 分辨率改变时的回调。"""
try:
selected_timing = self.local_dimming_timing_var.get()
self.log_gui.log(f"Local Dimming 分辨率已更改为: {selected_timing}", level="info")
self.config.current_test_types.setdefault("local_dimming", {})["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"Local Dimming 分辨率更改失败: {str(e)}", level="error")
def on_local_dimming_signal_format_changed(self: "PQAutomationApp", event=None):
"""Local Dimming ColorInfo 相关选项变更回调。"""
try:
color_space = self.local_dimming_color_space_var.get()
data_range = self.local_dimming_data_range_var.get()
bit_depth = self.local_dimming_bit_depth_var.get()
output_format = self.local_dimming_output_format_var.get()
ld_cfg = self.config.current_test_types.setdefault("local_dimming", {})
ld_cfg["colorimetry"] = color_space
ld_cfg["color_format"] = output_format
ld_cfg["bpc"] = UCDEnum.SignalFormat.BitDepth.get_bit_value(bit_depth)
ld_cfg["data_range"] = data_range
self.log_gui.log(
(
"Local Dimming 信号格式已更新: "
f"色彩空间={color_space}, 数据范围={data_range}, "
f"位深={bit_depth}, 色彩格式={output_format}"
),
level="info",
)
if self.testing:
self.log_gui.log("警告: 测试进行中,格式更改将在下次测试时生效", level="error")
self.save_pq_config()
return
if getattr(self.ucd, "status", False):
ok = self.signal_service.update_signal_format(
color_space=color_space,
data_range=data_range,
bit_depth=bit_depth,
output_format=output_format,
)
if not ok:
self.log_gui.log("Local Dimming 信号格式应用到UCD失败", level="error")
self.save_pq_config()
except Exception as e:
self.log_gui.log(f"Local Dimming 信号格式更改失败: {str(e)}", level="error")
def update_test_items(self: "PQAutomationApp"):
"""根据当前测试类型更新测试项目复选框"""
# 先隐藏所有测试项目框架
@@ -1023,6 +1164,7 @@ def update_test_items(self: "PQAutomationApp"):
)
# 添加复选框
toggle_bootstyle = "success-round-toggle"
for i, (text, var_name) in enumerate(config["items"]):
is_checked = var_name in saved_test_items
var = tk.BooleanVar(value=is_checked)
@@ -1032,7 +1174,7 @@ def update_test_items(self: "PQAutomationApp"):
frame,
text=text,
variable=var,
bootstyle="round-toggle",
bootstyle=toggle_bootstyle,
command=self.update_config_and_tabs,
).grid(row=i // 2 + 1, column=i % 2, sticky=tk.W, padx=10, pady=5)
@@ -1054,6 +1196,12 @@ def on_test_type_change(self: "PQAutomationApp"):
# SDR 选中时显示客户模版按钮
self.update_custom_button_visibility()
# Local Dimming 作为并列测试类型时,自动显示其专用面板。
if self.config.current_test_type == "local_dimming":
self.show_panel("local_dimming")
elif getattr(self, "current_panel", None) == "local_dimming":
self.hide_all_panels()
class MainLayoutMixin:
@@ -1074,5 +1222,7 @@ class MainLayoutMixin:
on_sdr_timing_changed = on_sdr_timing_changed
on_sdr_output_format_changed = on_sdr_output_format_changed
on_hdr_output_format_changed = on_hdr_output_format_changed
on_local_dimming_timing_changed = on_local_dimming_timing_changed
on_local_dimming_signal_format_changed = on_local_dimming_signal_format_changed
update_test_items = update_test_items
on_test_type_change = on_test_type_change