重构拆分plot图表
This commit is contained in:
@@ -315,4 +315,4 @@ def plot_accuracy(app, accuracy_data, test_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.accuracy_canvas.draw()
|
self.accuracy_canvas.draw()
|
||||||
self.chart_notebook.select(4)
|
self.chart_notebook.select(self.accuracy_chart_frame)
|
||||||
|
|||||||
@@ -320,6 +320,6 @@ def plot_cct(app, test_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.cct_canvas.draw()
|
self.cct_canvas.draw()
|
||||||
self.chart_notebook.select(2)
|
self.chart_notebook.select(self.cct_chart_frame)
|
||||||
|
|
||||||
self.log_gui.log("✓ xy 色度坐标图绘制完成")
|
self.log_gui.log("✓ xy 色度坐标图绘制完成")
|
||||||
|
|||||||
@@ -165,4 +165,4 @@ def plot_contrast(app, contrast_data, test_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.contrast_canvas.draw()
|
self.contrast_canvas.draw()
|
||||||
self.chart_notebook.select(3)
|
self.chart_notebook.select(self.contrast_chart_frame)
|
||||||
|
|||||||
@@ -138,6 +138,6 @@ def plot_gamma(app, L_bar, results_with_gamma_list, target_gamma, test_type):
|
|||||||
|
|
||||||
# ========== 4. 绘制到画布 ==========
|
# ========== 4. 绘制到画布 ==========
|
||||||
self.gamma_canvas.draw()
|
self.gamma_canvas.draw()
|
||||||
self.chart_notebook.select(1)
|
self.chart_notebook.select(self.gamma_chart_frame)
|
||||||
|
|
||||||
self.log_gui.log("Gamma曲线 + 数据表格绘制完成")
|
self.log_gui.log("Gamma曲线 + 数据表格绘制完成")
|
||||||
|
|||||||
@@ -534,6 +534,6 @@ def plot_gamut(app, results, coverage, test_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.gamut_canvas.draw()
|
self.gamut_canvas.draw()
|
||||||
self.chart_notebook.select(0)
|
self.chart_notebook.select(self.gamut_chart_frame)
|
||||||
|
|
||||||
self.log_gui.log("色域图绘制完成")
|
self.log_gui.log("色域图绘制完成")
|
||||||
|
|||||||
0
app/views/__init__.py
Normal file
0
app/views/__init__.py
Normal file
824
app/views/chart_frame.py
Normal file
824
app/views/chart_frame.py
Normal file
@@ -0,0 +1,824 @@
|
|||||||
|
"""图表框架相关逻辑(Step 3 重构)。
|
||||||
|
|
||||||
|
从 pqAutomationApp.PQAutomationApp 中搬迁而来。每个函数第一行 `self = app`
|
||||||
|
以保留原有 `self.xxx` 属性访问不变。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import tkinter as tk
|
||||||
|
import ttkbootstrap as ttk
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||||
|
from views.pq_debug_panel import PQDebugPanel
|
||||||
|
|
||||||
|
def init_gamut_chart(app):
|
||||||
|
"""初始化色域图表 - 手动设置subplot位置,完全避免重叠"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.gamut_chart_frame)
|
||||||
|
container.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
self.gamut_fig = plt.Figure(figsize=(14, 6), dpi=100)
|
||||||
|
self.gamut_canvas = FigureCanvasTkAgg(self.gamut_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.gamut_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
# ✅ 恢复原来的大尺寸:0.84 高度
|
||||||
|
self.gamut_ax_xy = self.gamut_fig.add_axes(
|
||||||
|
[0.02, 0.08, 0.46, 0.84]
|
||||||
|
) # ← 改回 0.84
|
||||||
|
self.gamut_ax_uv = self.gamut_fig.add_axes(
|
||||||
|
[0.52, 0.08, 0.46, 0.84]
|
||||||
|
) # ← 改回 0.84
|
||||||
|
|
||||||
|
# 初始化XY图
|
||||||
|
self.gamut_ax_xy.set_xlim(0, 600)
|
||||||
|
self.gamut_ax_xy.set_ylim(600, 0)
|
||||||
|
self.gamut_ax_xy.axis("off")
|
||||||
|
self.gamut_ax_xy.set_clip_on(False)
|
||||||
|
|
||||||
|
# 初始化UV图
|
||||||
|
self.gamut_ax_uv.set_xlim(0, 600)
|
||||||
|
self.gamut_ax_uv.set_ylim(600, 0)
|
||||||
|
self.gamut_ax_uv.axis("off")
|
||||||
|
self.gamut_ax_uv.set_clip_on(False)
|
||||||
|
|
||||||
|
# 调整标题位置:y=0.98
|
||||||
|
self.gamut_fig.suptitle("色域测试", fontsize=12, y=0.98)
|
||||||
|
|
||||||
|
self.gamut_canvas.draw()
|
||||||
|
|
||||||
|
def init_gamma_chart(app):
|
||||||
|
"""初始化Gamma曲线图表 - 左侧曲线 + 右侧表格(✅ 4列 + 通用说明)"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.gamma_chart_frame)
|
||||||
|
container.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
self.gamma_fig = plt.Figure(figsize=(12, 6), dpi=100, constrained_layout=False)
|
||||||
|
self.gamma_canvas = FigureCanvasTkAgg(self.gamma_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.gamma_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
# 左侧:Gamma 曲线
|
||||||
|
self.gamma_ax = self.gamma_fig.add_axes([0.08, 0.12, 0.50, 0.78])
|
||||||
|
self.gamma_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
||||||
|
self.gamma_ax.set_ylabel("L_bar", fontsize=10)
|
||||||
|
self.gamma_ax.set_xlim(0, 105)
|
||||||
|
self.gamma_ax.set_ylim(0, 1.1)
|
||||||
|
self.gamma_ax.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.gamma_ax.tick_params(labelsize=9)
|
||||||
|
|
||||||
|
# 左侧提示(通用说明,不显示具体 Gamma 值)
|
||||||
|
self.gamma_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
"等待测试数据...\n\n"
|
||||||
|
"将显示:\n"
|
||||||
|
"• 实测曲线 (蓝色)\n"
|
||||||
|
"• 理想 Gamma 曲线 (红色)\n\n"
|
||||||
|
"Gamma 值由测试配置决定",
|
||||||
|
ha="center",
|
||||||
|
va="center",
|
||||||
|
fontsize=10,
|
||||||
|
color="gray",
|
||||||
|
transform=self.gamma_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=1", facecolor="white", edgecolor="gray", alpha=0.8
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 右侧:数据表格
|
||||||
|
self.gamma_table_ax = self.gamma_fig.add_axes([0.62, 0.12, 0.35, 0.78])
|
||||||
|
self.gamma_table_ax.axis("off")
|
||||||
|
|
||||||
|
# 4列表格数据
|
||||||
|
table_data = [
|
||||||
|
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "Gamma"],
|
||||||
|
["0%", "--", "--", "--"],
|
||||||
|
["10%", "--", "--", "--"],
|
||||||
|
["20%", "--", "--", "--"],
|
||||||
|
["30%", "--", "--", "--"],
|
||||||
|
["40%", "--", "--", "--"],
|
||||||
|
["50%", "--", "--", "--"],
|
||||||
|
["60%", "--", "--", "--"],
|
||||||
|
["70%", "--", "--", "--"],
|
||||||
|
["80%", "--", "--", "--"],
|
||||||
|
["90%", "--", "--", "--"],
|
||||||
|
["100%", "--", "--", "--"],
|
||||||
|
]
|
||||||
|
|
||||||
|
table = self.gamma_table_ax.table(
|
||||||
|
cellText=table_data,
|
||||||
|
cellLoc="center",
|
||||||
|
loc="center",
|
||||||
|
colWidths=[0.18, 0.28, 0.27, 0.27], # ← 4列宽度
|
||||||
|
)
|
||||||
|
|
||||||
|
table.auto_set_font_size(False)
|
||||||
|
table.set_fontsize(7.5)
|
||||||
|
table.scale(1, 1.5)
|
||||||
|
|
||||||
|
# 表头样式
|
||||||
|
for i in range(4):
|
||||||
|
cell = table[(0, i)]
|
||||||
|
cell.set_facecolor("#4472C4")
|
||||||
|
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
||||||
|
|
||||||
|
# 数据行交替颜色
|
||||||
|
for i in range(1, len(table_data)):
|
||||||
|
for j in range(4):
|
||||||
|
cell = table[(i, j)]
|
||||||
|
if i % 2 == 0:
|
||||||
|
cell.set_facecolor("#E7E6E6")
|
||||||
|
else:
|
||||||
|
cell.set_facecolor("#FFFFFF")
|
||||||
|
|
||||||
|
# 底部说明
|
||||||
|
self.gamma_table_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.02,
|
||||||
|
"表格说明:\n"
|
||||||
|
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
||||||
|
"• L_bar: 归一化亮度 (0-1)\n"
|
||||||
|
"• Gamma: 实际 Gamma 值",
|
||||||
|
ha="center",
|
||||||
|
va="bottom",
|
||||||
|
fontsize=7,
|
||||||
|
color="gray",
|
||||||
|
transform=self.gamma_table_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=0.5",
|
||||||
|
facecolor="lightyellow",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.gamma_fig.suptitle("Gamma曲线 + 数据表格", fontsize=12, y=0.98)
|
||||||
|
self.gamma_canvas.draw()
|
||||||
|
|
||||||
|
def init_eotf_chart(app):
|
||||||
|
"""初始化 EOTF 曲线图表(HDR 专用)- 左侧曲线 + 右侧表格(✅ 4列)"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.eotf_chart_frame)
|
||||||
|
container.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
self.eotf_fig = plt.Figure(figsize=(12, 6), dpi=100, constrained_layout=False)
|
||||||
|
self.eotf_canvas = FigureCanvasTkAgg(self.eotf_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.eotf_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
||||||
|
|
||||||
|
# 左侧:EOTF 曲线
|
||||||
|
self.eotf_ax = self.eotf_fig.add_axes([0.08, 0.12, 0.50, 0.78])
|
||||||
|
self.eotf_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
||||||
|
self.eotf_ax.set_ylabel("L_bar (归一化亮度)", fontsize=10)
|
||||||
|
self.eotf_ax.set_xlim(0, 105)
|
||||||
|
self.eotf_ax.set_ylim(0, 1.1)
|
||||||
|
self.eotf_ax.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.eotf_ax.tick_params(labelsize=9)
|
||||||
|
|
||||||
|
# 左侧提示
|
||||||
|
self.eotf_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
"等待测试数据...\n\n将显示:\n• 实测 EOTF 曲线 (蓝色)\n• 理想 PQ 曲线 (红色)",
|
||||||
|
ha="center",
|
||||||
|
va="center",
|
||||||
|
fontsize=11,
|
||||||
|
color="gray",
|
||||||
|
transform=self.eotf_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=1", facecolor="white", edgecolor="gray", alpha=0.8
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 右侧:数据表格
|
||||||
|
self.eotf_table_ax = self.eotf_fig.add_axes([0.62, 0.12, 0.35, 0.78])
|
||||||
|
self.eotf_table_ax.axis("off")
|
||||||
|
|
||||||
|
# 4列表格数据
|
||||||
|
table_data = [
|
||||||
|
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "EOTF γ"],
|
||||||
|
["0%", "--", "--", "--"],
|
||||||
|
["10%", "--", "--", "--"],
|
||||||
|
["20%", "--", "--", "--"],
|
||||||
|
["30%", "--", "--", "--"],
|
||||||
|
["40%", "--", "--", "--"],
|
||||||
|
["50%", "--", "--", "--"],
|
||||||
|
["60%", "--", "--", "--"],
|
||||||
|
["70%", "--", "--", "--"],
|
||||||
|
["80%", "--", "--", "--"],
|
||||||
|
["90%", "--", "--", "--"],
|
||||||
|
["100%", "--", "--", "--"],
|
||||||
|
]
|
||||||
|
|
||||||
|
table = self.eotf_table_ax.table(
|
||||||
|
cellText=table_data,
|
||||||
|
cellLoc="center",
|
||||||
|
loc="center",
|
||||||
|
colWidths=[0.18, 0.28, 0.27, 0.27],
|
||||||
|
)
|
||||||
|
|
||||||
|
table.auto_set_font_size(False)
|
||||||
|
table.set_fontsize(7.5)
|
||||||
|
table.scale(1, 1.5)
|
||||||
|
|
||||||
|
# 表头样式
|
||||||
|
for i in range(4):
|
||||||
|
cell = table[(0, i)]
|
||||||
|
cell.set_facecolor("#4472C4")
|
||||||
|
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
||||||
|
|
||||||
|
# 数据行交替颜色
|
||||||
|
for i in range(1, len(table_data)):
|
||||||
|
for j in range(4):
|
||||||
|
cell = table[(i, j)]
|
||||||
|
if i % 2 == 0:
|
||||||
|
cell.set_facecolor("#E7E6E6")
|
||||||
|
else:
|
||||||
|
cell.set_facecolor("#FFFFFF")
|
||||||
|
|
||||||
|
# 底部说明
|
||||||
|
self.eotf_table_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.02,
|
||||||
|
"表格说明:\n"
|
||||||
|
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
||||||
|
"• L_bar: 归一化亮度 (0-1)\n"
|
||||||
|
"• EOTF γ: HDR 实际 Gamma 值",
|
||||||
|
ha="center",
|
||||||
|
va="bottom",
|
||||||
|
fontsize=7,
|
||||||
|
color="gray",
|
||||||
|
transform=self.eotf_table_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=0.5",
|
||||||
|
facecolor="lightyellow",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.eotf_fig.suptitle("EOTF 曲线 + 数据表格", fontsize=12, y=0.98)
|
||||||
|
self.eotf_canvas.draw()
|
||||||
|
|
||||||
|
def init_cct_chart(app):
|
||||||
|
"""初始化色度坐标图表 - 正向横坐标,标题居中最上方"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.cct_chart_frame)
|
||||||
|
container.pack(expand=True)
|
||||||
|
|
||||||
|
self.cct_fig = plt.Figure(figsize=(8, 6), dpi=100, tight_layout=False)
|
||||||
|
self.cct_canvas = FigureCanvasTkAgg(self.cct_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.cct_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack()
|
||||||
|
canvas_widget.config(width=800, height=600)
|
||||||
|
canvas_widget.pack_propagate(False)
|
||||||
|
|
||||||
|
self.cct_ax1 = self.cct_fig.add_subplot(211)
|
||||||
|
self.cct_ax2 = self.cct_fig.add_subplot(212)
|
||||||
|
|
||||||
|
# 上图:x coordinates
|
||||||
|
self.cct_ax1.set_xlabel("灰阶 (%)", fontsize=9)
|
||||||
|
self.cct_ax1.set_ylabel("CIE x", fontsize=9)
|
||||||
|
self.cct_ax1.set_xlim(0, 105)
|
||||||
|
self.cct_ax1.set_ylim(0.25, 0.35)
|
||||||
|
self.cct_ax1.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.cct_ax1.tick_params(labelsize=8)
|
||||||
|
|
||||||
|
# 下图:y coordinates
|
||||||
|
self.cct_ax2.set_xlabel("灰阶 (%)", fontsize=9)
|
||||||
|
self.cct_ax2.set_ylabel("CIE y", fontsize=9)
|
||||||
|
self.cct_ax2.set_xlim(0, 105)
|
||||||
|
self.cct_ax2.set_ylim(0.25, 0.35)
|
||||||
|
self.cct_ax2.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.cct_ax2.tick_params(labelsize=8)
|
||||||
|
|
||||||
|
# 调整标题位置:y=0.985(比色域/Gamma略高)
|
||||||
|
self.cct_fig.suptitle("色度一致性测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
self.cct_fig.subplots_adjust(
|
||||||
|
left=0.12,
|
||||||
|
right=0.88,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.08,
|
||||||
|
hspace=0.25,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cct_canvas.draw()
|
||||||
|
|
||||||
|
def init_contrast_chart(app):
|
||||||
|
"""初始化对比度图表 - 固定大小,居中显示"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.contrast_chart_frame)
|
||||||
|
container.pack(expand=True)
|
||||||
|
|
||||||
|
self.contrast_fig = plt.Figure(
|
||||||
|
figsize=(6, 6),
|
||||||
|
dpi=100,
|
||||||
|
tight_layout=False,
|
||||||
|
)
|
||||||
|
self.contrast_canvas = FigureCanvasTkAgg(self.contrast_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.contrast_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack()
|
||||||
|
|
||||||
|
canvas_widget.config(width=600, height=600)
|
||||||
|
canvas_widget.pack_propagate(False)
|
||||||
|
|
||||||
|
self.contrast_ax = self.contrast_fig.add_subplot(111)
|
||||||
|
self.contrast_ax.set_xlim(0, 1)
|
||||||
|
self.contrast_ax.set_ylim(0, 1)
|
||||||
|
self.contrast_ax.axis("off")
|
||||||
|
|
||||||
|
# 调整标题位置:y=0.985
|
||||||
|
self.contrast_fig.suptitle("对比度测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
self.contrast_fig.subplots_adjust(
|
||||||
|
left=0.02,
|
||||||
|
right=0.98,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.02,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.contrast_canvas.draw()
|
||||||
|
|
||||||
|
def init_accuracy_chart(app):
|
||||||
|
"""初始化色准图表 - 固定大小,居中显示"""
|
||||||
|
self = app
|
||||||
|
container = ttk.Frame(self.accuracy_chart_frame)
|
||||||
|
container.pack(expand=True)
|
||||||
|
|
||||||
|
self.accuracy_fig = plt.Figure(
|
||||||
|
figsize=(10, 6),
|
||||||
|
dpi=100,
|
||||||
|
tight_layout=False,
|
||||||
|
)
|
||||||
|
self.accuracy_canvas = FigureCanvasTkAgg(self.accuracy_fig, master=container)
|
||||||
|
|
||||||
|
canvas_widget = self.accuracy_canvas.get_tk_widget()
|
||||||
|
canvas_widget.pack()
|
||||||
|
|
||||||
|
canvas_widget.config(width=1000, height=600)
|
||||||
|
canvas_widget.pack_propagate(False)
|
||||||
|
|
||||||
|
self.accuracy_ax = self.accuracy_fig.add_subplot(111)
|
||||||
|
self.accuracy_ax.set_xlim(0, 1)
|
||||||
|
self.accuracy_ax.set_ylim(0, 1)
|
||||||
|
self.accuracy_ax.axis("off")
|
||||||
|
|
||||||
|
# 调整标题位置
|
||||||
|
self.accuracy_fig.suptitle("色准测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
self.accuracy_fig.subplots_adjust(
|
||||||
|
left=0.05,
|
||||||
|
right=0.95,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.05,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.accuracy_canvas.draw()
|
||||||
|
|
||||||
|
def clear_chart(app):
|
||||||
|
"""清空所有图表"""
|
||||||
|
self = app
|
||||||
|
|
||||||
|
# ========== 1. 清空色域图表 ==========
|
||||||
|
if hasattr(self, "gamut_ax_xy") and hasattr(self, "gamut_ax_uv"):
|
||||||
|
# 清空XY图
|
||||||
|
self.gamut_ax_xy.clear()
|
||||||
|
self.gamut_ax_xy.set_xlim(0, 600)
|
||||||
|
self.gamut_ax_xy.set_ylim(600, 0)
|
||||||
|
self.gamut_ax_xy.axis("off")
|
||||||
|
self.gamut_ax_xy.set_clip_on(False)
|
||||||
|
|
||||||
|
# 清空UV图
|
||||||
|
self.gamut_ax_uv.clear()
|
||||||
|
self.gamut_ax_uv.set_xlim(0, 600)
|
||||||
|
self.gamut_ax_uv.set_ylim(600, 0)
|
||||||
|
self.gamut_ax_uv.axis("off")
|
||||||
|
self.gamut_ax_uv.set_clip_on(False)
|
||||||
|
|
||||||
|
self.gamut_fig.suptitle("色域测试", fontsize=12, y=0.98)
|
||||||
|
self.gamut_canvas.draw()
|
||||||
|
|
||||||
|
# ========== 2. 清空Gamma图表(4列 + 通用说明)==========
|
||||||
|
if hasattr(self, "gamma_ax") and hasattr(self, "gamma_table_ax"):
|
||||||
|
# 清空左侧曲线
|
||||||
|
self.gamma_ax.clear()
|
||||||
|
self.gamma_ax.set_xlim(0, 105)
|
||||||
|
self.gamma_ax.set_ylim(0, 1.1)
|
||||||
|
self.gamma_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
||||||
|
self.gamma_ax.set_ylabel("L_bar", fontsize=10)
|
||||||
|
self.gamma_ax.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.gamma_ax.tick_params(labelsize=9)
|
||||||
|
|
||||||
|
# 左侧提示
|
||||||
|
self.gamma_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
"等待测试数据...\n\n"
|
||||||
|
"将显示:\n"
|
||||||
|
"• 实测曲线 (蓝色)\n"
|
||||||
|
"• 理想 Gamma 曲线 (红色)\n\n"
|
||||||
|
"Gamma 值由测试配置决定",
|
||||||
|
ha="center",
|
||||||
|
va="center",
|
||||||
|
fontsize=10,
|
||||||
|
color="gray",
|
||||||
|
transform=self.gamma_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=1",
|
||||||
|
facecolor="white",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 清空右侧表格
|
||||||
|
self.gamma_table_ax.clear()
|
||||||
|
self.gamma_table_ax.axis("off")
|
||||||
|
|
||||||
|
# 4列表格
|
||||||
|
table_data = [
|
||||||
|
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "Gamma"],
|
||||||
|
["0%", "--", "--", "--"],
|
||||||
|
["10%", "--", "--", "--"],
|
||||||
|
["20%", "--", "--", "--"],
|
||||||
|
["30%", "--", "--", "--"],
|
||||||
|
["40%", "--", "--", "--"],
|
||||||
|
["50%", "--", "--", "--"],
|
||||||
|
["60%", "--", "--", "--"],
|
||||||
|
["70%", "--", "--", "--"],
|
||||||
|
["80%", "--", "--", "--"],
|
||||||
|
["90%", "--", "--", "--"],
|
||||||
|
["100%", "--", "--", "--"],
|
||||||
|
]
|
||||||
|
|
||||||
|
table = self.gamma_table_ax.table(
|
||||||
|
cellText=table_data,
|
||||||
|
cellLoc="center",
|
||||||
|
loc="center",
|
||||||
|
colWidths=[0.18, 0.28, 0.27, 0.27],
|
||||||
|
)
|
||||||
|
|
||||||
|
table.auto_set_font_size(False)
|
||||||
|
table.set_fontsize(7.5)
|
||||||
|
table.scale(1, 1.5)
|
||||||
|
|
||||||
|
# 表头样式
|
||||||
|
for i in range(4):
|
||||||
|
cell = table[(0, i)]
|
||||||
|
cell.set_facecolor("#4472C4")
|
||||||
|
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
||||||
|
|
||||||
|
# 数据行交替颜色
|
||||||
|
for i in range(1, len(table_data)):
|
||||||
|
for j in range(4):
|
||||||
|
cell = table[(i, j)]
|
||||||
|
if i % 2 == 0:
|
||||||
|
cell.set_facecolor("#E7E6E6")
|
||||||
|
else:
|
||||||
|
cell.set_facecolor("#FFFFFF")
|
||||||
|
|
||||||
|
# 底部说明
|
||||||
|
self.gamma_table_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.02,
|
||||||
|
"表格说明:\n"
|
||||||
|
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
||||||
|
"• L_bar: 归一化亮度 (0-1)\n"
|
||||||
|
"• Gamma: 实际 Gamma 值",
|
||||||
|
ha="center",
|
||||||
|
va="bottom",
|
||||||
|
fontsize=7,
|
||||||
|
color="gray",
|
||||||
|
transform=self.gamma_table_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=0.5",
|
||||||
|
facecolor="lightyellow",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.gamma_fig.suptitle("Gamma曲线 + 数据表格", fontsize=12, y=0.98)
|
||||||
|
self.gamma_canvas.draw()
|
||||||
|
|
||||||
|
# ========== 3. 清空EOTF图表(4列)==========
|
||||||
|
if hasattr(self, "eotf_ax") and hasattr(self, "eotf_table_ax"):
|
||||||
|
# 清空左侧曲线
|
||||||
|
self.eotf_ax.clear()
|
||||||
|
self.eotf_ax.set_xlim(0, 105)
|
||||||
|
self.eotf_ax.set_ylim(0, 1.1)
|
||||||
|
self.eotf_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
||||||
|
self.eotf_ax.set_ylabel("L_bar (归一化亮度)", fontsize=10)
|
||||||
|
self.eotf_ax.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.eotf_ax.tick_params(labelsize=9)
|
||||||
|
|
||||||
|
# 左侧提示
|
||||||
|
self.eotf_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.5,
|
||||||
|
"等待测试数据...\n\n将显示:\n• 实测 EOTF 曲线 (蓝色)\n• 理想 PQ 曲线 (红色)",
|
||||||
|
ha="center",
|
||||||
|
va="center",
|
||||||
|
fontsize=11,
|
||||||
|
color="gray",
|
||||||
|
transform=self.eotf_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=1",
|
||||||
|
facecolor="white",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 清空右侧表格
|
||||||
|
self.eotf_table_ax.clear()
|
||||||
|
self.eotf_table_ax.axis("off")
|
||||||
|
|
||||||
|
# 4列表格
|
||||||
|
table_data = [
|
||||||
|
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "EOTF γ"],
|
||||||
|
["0%", "--", "--", "--"],
|
||||||
|
["10%", "--", "--", "--"],
|
||||||
|
["20%", "--", "--", "--"],
|
||||||
|
["30%", "--", "--", "--"],
|
||||||
|
["40%", "--", "--", "--"],
|
||||||
|
["50%", "--", "--", "--"],
|
||||||
|
["60%", "--", "--", "--"],
|
||||||
|
["70%", "--", "--", "--"],
|
||||||
|
["80%", "--", "--", "--"],
|
||||||
|
["90%", "--", "--", "--"],
|
||||||
|
["100%", "--", "--", "--"],
|
||||||
|
]
|
||||||
|
|
||||||
|
table = self.eotf_table_ax.table(
|
||||||
|
cellText=table_data,
|
||||||
|
cellLoc="center",
|
||||||
|
loc="center",
|
||||||
|
colWidths=[0.18, 0.28, 0.27, 0.27],
|
||||||
|
)
|
||||||
|
|
||||||
|
table.auto_set_font_size(False)
|
||||||
|
table.set_fontsize(7.5)
|
||||||
|
table.scale(1, 1.5)
|
||||||
|
|
||||||
|
# 表头样式
|
||||||
|
for i in range(4):
|
||||||
|
cell = table[(0, i)]
|
||||||
|
cell.set_facecolor("#4472C4")
|
||||||
|
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
||||||
|
|
||||||
|
# 数据行交替颜色
|
||||||
|
for i in range(1, len(table_data)):
|
||||||
|
for j in range(4):
|
||||||
|
cell = table[(i, j)]
|
||||||
|
if i % 2 == 0:
|
||||||
|
cell.set_facecolor("#E7E6E6")
|
||||||
|
else:
|
||||||
|
cell.set_facecolor("#FFFFFF")
|
||||||
|
|
||||||
|
# 底部说明
|
||||||
|
self.eotf_table_ax.text(
|
||||||
|
0.5,
|
||||||
|
0.02,
|
||||||
|
"表格说明:\n"
|
||||||
|
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
||||||
|
"• L_bar: 归一化亮度 (0-1)\n"
|
||||||
|
"• EOTF γ: HDR 实际 Gamma 值",
|
||||||
|
ha="center",
|
||||||
|
va="bottom",
|
||||||
|
fontsize=7,
|
||||||
|
color="gray",
|
||||||
|
transform=self.eotf_table_ax.transAxes,
|
||||||
|
bbox=dict(
|
||||||
|
boxstyle="round,pad=0.5",
|
||||||
|
facecolor="lightyellow",
|
||||||
|
edgecolor="gray",
|
||||||
|
alpha=0.8,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.eotf_fig.suptitle("EOTF 曲线 + 数据表格", fontsize=12, y=0.98)
|
||||||
|
self.eotf_canvas.draw()
|
||||||
|
|
||||||
|
# ========== 4. 清空色度图表 ==========
|
||||||
|
if hasattr(self, "cct_ax1") and hasattr(self, "cct_ax2"):
|
||||||
|
# 上图:x coordinates
|
||||||
|
self.cct_ax1.clear()
|
||||||
|
self.cct_ax1.set_xlabel("灰阶 (%)", fontsize=9)
|
||||||
|
self.cct_ax1.set_ylabel("CIE x", fontsize=9)
|
||||||
|
self.cct_ax1.set_xlim(0, 105)
|
||||||
|
self.cct_ax1.set_ylim(0.25, 0.35)
|
||||||
|
self.cct_ax1.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.cct_ax1.tick_params(labelsize=8)
|
||||||
|
|
||||||
|
# 下图:y coordinates
|
||||||
|
self.cct_ax2.clear()
|
||||||
|
self.cct_ax2.set_xlabel("灰阶 (%)", fontsize=9)
|
||||||
|
self.cct_ax2.set_ylabel("CIE y", fontsize=9)
|
||||||
|
self.cct_ax2.set_xlim(0, 105)
|
||||||
|
self.cct_ax2.set_ylim(0.25, 0.35)
|
||||||
|
self.cct_ax2.grid(True, linestyle="--", alpha=0.3)
|
||||||
|
self.cct_ax2.tick_params(labelsize=8)
|
||||||
|
|
||||||
|
self.cct_fig.suptitle("色度一致性测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
# 重置布局
|
||||||
|
self.cct_fig.subplots_adjust(
|
||||||
|
left=0.12,
|
||||||
|
right=0.88,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.08,
|
||||||
|
hspace=0.25,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cct_canvas.draw()
|
||||||
|
|
||||||
|
# ========== 5. 清空对比度图表 ==========
|
||||||
|
if hasattr(self, "contrast_ax"):
|
||||||
|
self.contrast_ax.clear()
|
||||||
|
self.contrast_ax.set_xlim(0, 1)
|
||||||
|
self.contrast_ax.set_ylim(0, 1)
|
||||||
|
self.contrast_ax.axis("off")
|
||||||
|
|
||||||
|
self.contrast_fig.suptitle("对比度测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
# 重置布局
|
||||||
|
self.contrast_fig.subplots_adjust(
|
||||||
|
left=0.02,
|
||||||
|
right=0.98,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.02,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.contrast_canvas.draw()
|
||||||
|
|
||||||
|
# ========== 6. 清空色准图表 ==========
|
||||||
|
if hasattr(self, "accuracy_ax"):
|
||||||
|
self.accuracy_ax.clear()
|
||||||
|
self.accuracy_ax.set_xlim(0, 1)
|
||||||
|
self.accuracy_ax.set_ylim(0, 1)
|
||||||
|
self.accuracy_ax.axis("off")
|
||||||
|
|
||||||
|
# 标题
|
||||||
|
self.accuracy_fig.suptitle("色准测试", fontsize=12, y=0.985)
|
||||||
|
|
||||||
|
# 重置布局
|
||||||
|
self.accuracy_fig.subplots_adjust(
|
||||||
|
left=0.05,
|
||||||
|
right=0.95,
|
||||||
|
top=0.90,
|
||||||
|
bottom=0.05,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.accuracy_canvas.draw()
|
||||||
|
|
||||||
|
def update_chart_tabs_state(app):
|
||||||
|
"""根据测试项目复选框状态动态增删图表 Tab(保持规范顺序)。
|
||||||
|
|
||||||
|
- 色域 / Gamma 或 EOTF / 色度一致性 / 对比度 / 色准 全部走动态 add/forget
|
||||||
|
- Gamma 与 EOTF 二选一,由 current_test_type 决定
|
||||||
|
- 屏模组测试强制隐藏色准 Tab
|
||||||
|
- 客户模板 Tab 由 change_test_type 独立管理,这里不动
|
||||||
|
"""
|
||||||
|
self = app
|
||||||
|
if not hasattr(self, "chart_notebook"):
|
||||||
|
return
|
||||||
|
|
||||||
|
selected_items = self.get_selected_test_items()
|
||||||
|
current_test_type = self.config.current_test_type
|
||||||
|
|
||||||
|
# 根据测试类型决定 gamma/eotf 显示哪一个
|
||||||
|
if current_test_type == "hdr_movie":
|
||||||
|
gamma_like_frame = self.eotf_chart_frame
|
||||||
|
gamma_like_text = "EOTF 曲线"
|
||||||
|
gamma_like_other = self.gamma_chart_frame
|
||||||
|
else:
|
||||||
|
gamma_like_frame = self.gamma_chart_frame
|
||||||
|
gamma_like_text = "Gamma 曲线"
|
||||||
|
gamma_like_other = self.eotf_chart_frame
|
||||||
|
|
||||||
|
want_gamut = "gamut" in selected_items
|
||||||
|
want_gamma_like = "gamma" in selected_items or "eotf" in selected_items
|
||||||
|
want_cct = "cct" in selected_items
|
||||||
|
want_contrast = "contrast" in selected_items
|
||||||
|
want_accuracy = (
|
||||||
|
"accuracy" in selected_items and current_test_type != "screen_module"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 规范顺序:色域 → Gamma/EOTF → 色度一致性 → 对比度 → 色准
|
||||||
|
spec = [
|
||||||
|
(want_gamut, self.gamut_chart_frame, "色域图"),
|
||||||
|
(want_gamma_like, gamma_like_frame, gamma_like_text),
|
||||||
|
(want_cct, self.cct_chart_frame, "色度一致性"),
|
||||||
|
(want_contrast, self.contrast_chart_frame, "对比度"),
|
||||||
|
(want_accuracy, self.accuracy_chart_frame, "色准"),
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 始终先把"另一个" gamma/eotf frame 从 Notebook 移除,保持互斥
|
||||||
|
current_ids = list(self.chart_notebook.tabs())
|
||||||
|
if str(gamma_like_other) in current_ids:
|
||||||
|
self.chart_notebook.forget(gamma_like_other)
|
||||||
|
|
||||||
|
# 按规范顺序处理 add/forget
|
||||||
|
for idx_in_spec, (want, frame, text) in enumerate(spec):
|
||||||
|
fid = str(frame)
|
||||||
|
present = fid in self.chart_notebook.tabs()
|
||||||
|
|
||||||
|
if want and not present:
|
||||||
|
# 统计该 frame 在 spec 中前面、当前实际存在的 tab 数 → 插入位置
|
||||||
|
current_ids = list(self.chart_notebook.tabs())
|
||||||
|
pos = sum(
|
||||||
|
1 for pre_want, pre_frame, _ in spec[:idx_in_spec]
|
||||||
|
if str(pre_frame) in current_ids
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
self.chart_notebook.insert(pos, frame, text=text)
|
||||||
|
except Exception:
|
||||||
|
# fallback:尾部 add
|
||||||
|
self.chart_notebook.add(frame, text=text)
|
||||||
|
|
||||||
|
elif not want and present:
|
||||||
|
self.chart_notebook.forget(frame)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
if hasattr(self, "log_gui"):
|
||||||
|
self.log_gui.log(f"更新Tab状态失败: {str(e)}")
|
||||||
|
|
||||||
|
def create_result_chart_frame(app):
|
||||||
|
"""创建结果图表区域 - 6个独立Tab(Gamma 和 EOTF 分离)"""
|
||||||
|
self = app
|
||||||
|
# 创建Notebook用于图表切换
|
||||||
|
self.chart_notebook = ttk.Notebook(self.result_frame)
|
||||||
|
self.chart_notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
||||||
|
|
||||||
|
# ========== 创建6个独立的Tab页面 ==========
|
||||||
|
# 1. 色域图页面
|
||||||
|
self.gamut_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 2. Gamma图页面(SDR/屏模组使用)
|
||||||
|
self.gamma_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 3. EOTF图页面(HDR专用)
|
||||||
|
self.eotf_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 4. 色度一致性页面
|
||||||
|
self.cct_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 5. 对比度页面
|
||||||
|
self.contrast_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 6. 色准页面
|
||||||
|
self.accuracy_chart_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# 7. 客户模板结果页面
|
||||||
|
self.custom_template_tab_frame = ttk.Frame(self.chart_notebook)
|
||||||
|
|
||||||
|
# ========== 添加到Notebook(初始只添加前5个)==========
|
||||||
|
self.chart_notebook.add(self.gamut_chart_frame, text="色域图")
|
||||||
|
self.chart_notebook.add(self.gamma_chart_frame, text="Gamma曲线")
|
||||||
|
# ← EOTF 不添加,由 change_test_type() 动态控制
|
||||||
|
self.chart_notebook.add(self.cct_chart_frame, text="色度一致性")
|
||||||
|
self.chart_notebook.add(self.contrast_chart_frame, text="对比度")
|
||||||
|
self.chart_notebook.add(self.accuracy_chart_frame, text="色准")
|
||||||
|
|
||||||
|
# 初始化六个独立的图表
|
||||||
|
self.init_gamut_chart()
|
||||||
|
self.init_gamma_chart()
|
||||||
|
self.init_eotf_chart()
|
||||||
|
self.init_cct_chart()
|
||||||
|
self.init_contrast_chart()
|
||||||
|
self.init_accuracy_chart()
|
||||||
|
|
||||||
|
# 绑定Tab切换事件
|
||||||
|
self.chart_notebook.bind("<<NotebookTabChanged>>", self.on_chart_tab_changed)
|
||||||
|
|
||||||
|
# ==================== ✅ 在图表下方创建单步调试面板 ====================
|
||||||
|
self.debug_container = ttk.LabelFrame(
|
||||||
|
self.result_frame, # ← 放在 result_frame 内,图表正下方
|
||||||
|
text="🔧 单步调试",
|
||||||
|
padding=10,
|
||||||
|
)
|
||||||
|
# 默认不显示
|
||||||
|
|
||||||
|
# 创建单步调试面板实例
|
||||||
|
self.debug_panel = PQDebugPanel(self.debug_container, self)
|
||||||
|
|
||||||
|
self.log_gui.log("✓ 单步调试面板已创建(放在测试结果图表下方)")
|
||||||
|
|
||||||
|
def on_chart_tab_changed(app, event):
|
||||||
|
"""Tab切换时的事件处理"""
|
||||||
|
self = app
|
||||||
|
try:
|
||||||
|
self._last_tab_index = self.chart_notebook.index(
|
||||||
|
self.chart_notebook.select()
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self.log_gui.log(f"Tab切换事件处理失败: {str(e)}")
|
||||||
|
|
||||||
@@ -53,6 +53,18 @@ from app.plots.plot_contrast import plot_contrast as _plot_contrast
|
|||||||
from app.plots.plot_eotf import plot_eotf as _plot_eotf
|
from app.plots.plot_eotf import plot_eotf as _plot_eotf
|
||||||
from app.plots.plot_gamma import plot_gamma as _plot_gamma
|
from app.plots.plot_gamma import plot_gamma as _plot_gamma
|
||||||
from app.plots.plot_gamut import plot_gamut as _plot_gamut
|
from app.plots.plot_gamut import plot_gamut as _plot_gamut
|
||||||
|
from app.views.chart_frame import (
|
||||||
|
clear_chart as _cf_clear_chart,
|
||||||
|
create_result_chart_frame as _cf_create_result_chart_frame,
|
||||||
|
init_accuracy_chart as _cf_init_accuracy_chart,
|
||||||
|
init_cct_chart as _cf_init_cct_chart,
|
||||||
|
init_contrast_chart as _cf_init_contrast_chart,
|
||||||
|
init_eotf_chart as _cf_init_eotf_chart,
|
||||||
|
init_gamma_chart as _cf_init_gamma_chart,
|
||||||
|
init_gamut_chart as _cf_init_gamut_chart,
|
||||||
|
on_chart_tab_changed as _cf_on_chart_tab_changed,
|
||||||
|
update_chart_tabs_state as _cf_update_chart_tabs_state,
|
||||||
|
)
|
||||||
|
|
||||||
plt.rcParams["font.family"] = ["sans-serif"]
|
plt.rcParams["font.family"] = ["sans-serif"]
|
||||||
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
|
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"]
|
||||||
@@ -210,666 +222,26 @@ class PQAutomationApp:
|
|||||||
self.log_gui.log(f"初始化默认测试类型失败: {str(e)}")
|
self.log_gui.log(f"初始化默认测试类型失败: {str(e)}")
|
||||||
|
|
||||||
def init_gamut_chart(self):
|
def init_gamut_chart(self):
|
||||||
"""初始化色域图表 - 手动设置subplot位置,完全避免重叠"""
|
"""转发到 app.views.chart_frame.init_gamut_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.gamut_chart_frame)
|
return _cf_init_gamut_chart(self)
|
||||||
container.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
self.gamut_fig = plt.Figure(figsize=(14, 6), dpi=100)
|
|
||||||
self.gamut_canvas = FigureCanvasTkAgg(self.gamut_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.gamut_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
# ✅ 恢复原来的大尺寸:0.84 高度
|
|
||||||
self.gamut_ax_xy = self.gamut_fig.add_axes(
|
|
||||||
[0.02, 0.08, 0.46, 0.84]
|
|
||||||
) # ← 改回 0.84
|
|
||||||
self.gamut_ax_uv = self.gamut_fig.add_axes(
|
|
||||||
[0.52, 0.08, 0.46, 0.84]
|
|
||||||
) # ← 改回 0.84
|
|
||||||
|
|
||||||
# 初始化XY图
|
|
||||||
self.gamut_ax_xy.set_xlim(0, 600)
|
|
||||||
self.gamut_ax_xy.set_ylim(600, 0)
|
|
||||||
self.gamut_ax_xy.axis("off")
|
|
||||||
self.gamut_ax_xy.set_clip_on(False)
|
|
||||||
|
|
||||||
# 初始化UV图
|
|
||||||
self.gamut_ax_uv.set_xlim(0, 600)
|
|
||||||
self.gamut_ax_uv.set_ylim(600, 0)
|
|
||||||
self.gamut_ax_uv.axis("off")
|
|
||||||
self.gamut_ax_uv.set_clip_on(False)
|
|
||||||
|
|
||||||
# 调整标题位置:y=0.98
|
|
||||||
self.gamut_fig.suptitle("色域测试", fontsize=12, y=0.98)
|
|
||||||
|
|
||||||
self.gamut_canvas.draw()
|
|
||||||
|
|
||||||
def init_gamma_chart(self):
|
def init_gamma_chart(self):
|
||||||
"""初始化Gamma曲线图表 - 左侧曲线 + 右侧表格(✅ 4列 + 通用说明)"""
|
"""转发到 app.views.chart_frame.init_gamma_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.gamma_chart_frame)
|
return _cf_init_gamma_chart(self)
|
||||||
container.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
self.gamma_fig = plt.Figure(figsize=(12, 6), dpi=100, constrained_layout=False)
|
|
||||||
self.gamma_canvas = FigureCanvasTkAgg(self.gamma_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.gamma_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
# 左侧:Gamma 曲线
|
|
||||||
self.gamma_ax = self.gamma_fig.add_axes([0.08, 0.12, 0.50, 0.78])
|
|
||||||
self.gamma_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
|
||||||
self.gamma_ax.set_ylabel("L_bar", fontsize=10)
|
|
||||||
self.gamma_ax.set_xlim(0, 105)
|
|
||||||
self.gamma_ax.set_ylim(0, 1.1)
|
|
||||||
self.gamma_ax.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.gamma_ax.tick_params(labelsize=9)
|
|
||||||
|
|
||||||
# 左侧提示(通用说明,不显示具体 Gamma 值)
|
|
||||||
self.gamma_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
"等待测试数据...\n\n"
|
|
||||||
"将显示:\n"
|
|
||||||
"• 实测曲线 (蓝色)\n"
|
|
||||||
"• 理想 Gamma 曲线 (红色)\n\n"
|
|
||||||
"Gamma 值由测试配置决定",
|
|
||||||
ha="center",
|
|
||||||
va="center",
|
|
||||||
fontsize=10,
|
|
||||||
color="gray",
|
|
||||||
transform=self.gamma_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=1", facecolor="white", edgecolor="gray", alpha=0.8
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 右侧:数据表格
|
|
||||||
self.gamma_table_ax = self.gamma_fig.add_axes([0.62, 0.12, 0.35, 0.78])
|
|
||||||
self.gamma_table_ax.axis("off")
|
|
||||||
|
|
||||||
# 4列表格数据
|
|
||||||
table_data = [
|
|
||||||
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "Gamma"],
|
|
||||||
["0%", "--", "--", "--"],
|
|
||||||
["10%", "--", "--", "--"],
|
|
||||||
["20%", "--", "--", "--"],
|
|
||||||
["30%", "--", "--", "--"],
|
|
||||||
["40%", "--", "--", "--"],
|
|
||||||
["50%", "--", "--", "--"],
|
|
||||||
["60%", "--", "--", "--"],
|
|
||||||
["70%", "--", "--", "--"],
|
|
||||||
["80%", "--", "--", "--"],
|
|
||||||
["90%", "--", "--", "--"],
|
|
||||||
["100%", "--", "--", "--"],
|
|
||||||
]
|
|
||||||
|
|
||||||
table = self.gamma_table_ax.table(
|
|
||||||
cellText=table_data,
|
|
||||||
cellLoc="center",
|
|
||||||
loc="center",
|
|
||||||
colWidths=[0.18, 0.28, 0.27, 0.27], # ← 4列宽度
|
|
||||||
)
|
|
||||||
|
|
||||||
table.auto_set_font_size(False)
|
|
||||||
table.set_fontsize(7.5)
|
|
||||||
table.scale(1, 1.5)
|
|
||||||
|
|
||||||
# 表头样式
|
|
||||||
for i in range(4):
|
|
||||||
cell = table[(0, i)]
|
|
||||||
cell.set_facecolor("#4472C4")
|
|
||||||
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
|
||||||
|
|
||||||
# 数据行交替颜色
|
|
||||||
for i in range(1, len(table_data)):
|
|
||||||
for j in range(4):
|
|
||||||
cell = table[(i, j)]
|
|
||||||
if i % 2 == 0:
|
|
||||||
cell.set_facecolor("#E7E6E6")
|
|
||||||
else:
|
|
||||||
cell.set_facecolor("#FFFFFF")
|
|
||||||
|
|
||||||
# 底部说明
|
|
||||||
self.gamma_table_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.02,
|
|
||||||
"表格说明:\n"
|
|
||||||
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
|
||||||
"• L_bar: 归一化亮度 (0-1)\n"
|
|
||||||
"• Gamma: 实际 Gamma 值",
|
|
||||||
ha="center",
|
|
||||||
va="bottom",
|
|
||||||
fontsize=7,
|
|
||||||
color="gray",
|
|
||||||
transform=self.gamma_table_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=0.5",
|
|
||||||
facecolor="lightyellow",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.gamma_fig.suptitle("Gamma曲线 + 数据表格", fontsize=12, y=0.98)
|
|
||||||
self.gamma_canvas.draw()
|
|
||||||
|
|
||||||
def init_eotf_chart(self):
|
def init_eotf_chart(self):
|
||||||
"""初始化 EOTF 曲线图表(HDR 专用)- 左侧曲线 + 右侧表格(✅ 4列)"""
|
"""转发到 app.views.chart_frame.init_eotf_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.eotf_chart_frame)
|
return _cf_init_eotf_chart(self)
|
||||||
container.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
self.eotf_fig = plt.Figure(figsize=(12, 6), dpi=100, constrained_layout=False)
|
|
||||||
self.eotf_canvas = FigureCanvasTkAgg(self.eotf_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.eotf_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack(expand=True, fill=tk.BOTH)
|
|
||||||
|
|
||||||
# 左侧:EOTF 曲线
|
|
||||||
self.eotf_ax = self.eotf_fig.add_axes([0.08, 0.12, 0.50, 0.78])
|
|
||||||
self.eotf_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
|
||||||
self.eotf_ax.set_ylabel("L_bar (归一化亮度)", fontsize=10)
|
|
||||||
self.eotf_ax.set_xlim(0, 105)
|
|
||||||
self.eotf_ax.set_ylim(0, 1.1)
|
|
||||||
self.eotf_ax.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.eotf_ax.tick_params(labelsize=9)
|
|
||||||
|
|
||||||
# 左侧提示
|
|
||||||
self.eotf_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
"等待测试数据...\n\n将显示:\n• 实测 EOTF 曲线 (蓝色)\n• 理想 PQ 曲线 (红色)",
|
|
||||||
ha="center",
|
|
||||||
va="center",
|
|
||||||
fontsize=11,
|
|
||||||
color="gray",
|
|
||||||
transform=self.eotf_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=1", facecolor="white", edgecolor="gray", alpha=0.8
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 右侧:数据表格
|
|
||||||
self.eotf_table_ax = self.eotf_fig.add_axes([0.62, 0.12, 0.35, 0.78])
|
|
||||||
self.eotf_table_ax.axis("off")
|
|
||||||
|
|
||||||
# 4列表格数据
|
|
||||||
table_data = [
|
|
||||||
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "EOTF γ"],
|
|
||||||
["0%", "--", "--", "--"],
|
|
||||||
["10%", "--", "--", "--"],
|
|
||||||
["20%", "--", "--", "--"],
|
|
||||||
["30%", "--", "--", "--"],
|
|
||||||
["40%", "--", "--", "--"],
|
|
||||||
["50%", "--", "--", "--"],
|
|
||||||
["60%", "--", "--", "--"],
|
|
||||||
["70%", "--", "--", "--"],
|
|
||||||
["80%", "--", "--", "--"],
|
|
||||||
["90%", "--", "--", "--"],
|
|
||||||
["100%", "--", "--", "--"],
|
|
||||||
]
|
|
||||||
|
|
||||||
table = self.eotf_table_ax.table(
|
|
||||||
cellText=table_data,
|
|
||||||
cellLoc="center",
|
|
||||||
loc="center",
|
|
||||||
colWidths=[0.18, 0.28, 0.27, 0.27],
|
|
||||||
)
|
|
||||||
|
|
||||||
table.auto_set_font_size(False)
|
|
||||||
table.set_fontsize(7.5)
|
|
||||||
table.scale(1, 1.5)
|
|
||||||
|
|
||||||
# 表头样式
|
|
||||||
for i in range(4):
|
|
||||||
cell = table[(0, i)]
|
|
||||||
cell.set_facecolor("#4472C4")
|
|
||||||
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
|
||||||
|
|
||||||
# 数据行交替颜色
|
|
||||||
for i in range(1, len(table_data)):
|
|
||||||
for j in range(4):
|
|
||||||
cell = table[(i, j)]
|
|
||||||
if i % 2 == 0:
|
|
||||||
cell.set_facecolor("#E7E6E6")
|
|
||||||
else:
|
|
||||||
cell.set_facecolor("#FFFFFF")
|
|
||||||
|
|
||||||
# 底部说明
|
|
||||||
self.eotf_table_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.02,
|
|
||||||
"表格说明:\n"
|
|
||||||
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
|
||||||
"• L_bar: 归一化亮度 (0-1)\n"
|
|
||||||
"• EOTF γ: HDR 实际 Gamma 值",
|
|
||||||
ha="center",
|
|
||||||
va="bottom",
|
|
||||||
fontsize=7,
|
|
||||||
color="gray",
|
|
||||||
transform=self.eotf_table_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=0.5",
|
|
||||||
facecolor="lightyellow",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.eotf_fig.suptitle("EOTF 曲线 + 数据表格", fontsize=12, y=0.98)
|
|
||||||
self.eotf_canvas.draw()
|
|
||||||
|
|
||||||
def init_cct_chart(self):
|
def init_cct_chart(self):
|
||||||
"""初始化色度坐标图表 - 正向横坐标,标题居中最上方"""
|
"""转发到 app.views.chart_frame.init_cct_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.cct_chart_frame)
|
return _cf_init_cct_chart(self)
|
||||||
container.pack(expand=True)
|
|
||||||
|
|
||||||
self.cct_fig = plt.Figure(figsize=(8, 6), dpi=100, tight_layout=False)
|
|
||||||
self.cct_canvas = FigureCanvasTkAgg(self.cct_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.cct_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack()
|
|
||||||
canvas_widget.config(width=800, height=600)
|
|
||||||
canvas_widget.pack_propagate(False)
|
|
||||||
|
|
||||||
self.cct_ax1 = self.cct_fig.add_subplot(211)
|
|
||||||
self.cct_ax2 = self.cct_fig.add_subplot(212)
|
|
||||||
|
|
||||||
# 上图:x coordinates
|
|
||||||
self.cct_ax1.set_xlabel("灰阶 (%)", fontsize=9)
|
|
||||||
self.cct_ax1.set_ylabel("CIE x", fontsize=9)
|
|
||||||
self.cct_ax1.set_xlim(0, 105)
|
|
||||||
self.cct_ax1.set_ylim(0.25, 0.35)
|
|
||||||
self.cct_ax1.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.cct_ax1.tick_params(labelsize=8)
|
|
||||||
|
|
||||||
# 下图:y coordinates
|
|
||||||
self.cct_ax2.set_xlabel("灰阶 (%)", fontsize=9)
|
|
||||||
self.cct_ax2.set_ylabel("CIE y", fontsize=9)
|
|
||||||
self.cct_ax2.set_xlim(0, 105)
|
|
||||||
self.cct_ax2.set_ylim(0.25, 0.35)
|
|
||||||
self.cct_ax2.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.cct_ax2.tick_params(labelsize=8)
|
|
||||||
|
|
||||||
# 调整标题位置:y=0.985(比色域/Gamma略高)
|
|
||||||
self.cct_fig.suptitle("色度一致性测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
self.cct_fig.subplots_adjust(
|
|
||||||
left=0.12,
|
|
||||||
right=0.88,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.08,
|
|
||||||
hspace=0.25,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.cct_canvas.draw()
|
|
||||||
|
|
||||||
def init_contrast_chart(self):
|
def init_contrast_chart(self):
|
||||||
"""初始化对比度图表 - 固定大小,居中显示"""
|
"""转发到 app.views.chart_frame.init_contrast_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.contrast_chart_frame)
|
return _cf_init_contrast_chart(self)
|
||||||
container.pack(expand=True)
|
|
||||||
|
|
||||||
self.contrast_fig = plt.Figure(
|
|
||||||
figsize=(6, 6),
|
|
||||||
dpi=100,
|
|
||||||
tight_layout=False,
|
|
||||||
)
|
|
||||||
self.contrast_canvas = FigureCanvasTkAgg(self.contrast_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.contrast_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack()
|
|
||||||
|
|
||||||
canvas_widget.config(width=600, height=600)
|
|
||||||
canvas_widget.pack_propagate(False)
|
|
||||||
|
|
||||||
self.contrast_ax = self.contrast_fig.add_subplot(111)
|
|
||||||
self.contrast_ax.set_xlim(0, 1)
|
|
||||||
self.contrast_ax.set_ylim(0, 1)
|
|
||||||
self.contrast_ax.axis("off")
|
|
||||||
|
|
||||||
# 调整标题位置:y=0.985
|
|
||||||
self.contrast_fig.suptitle("对比度测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
self.contrast_fig.subplots_adjust(
|
|
||||||
left=0.02,
|
|
||||||
right=0.98,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.02,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.contrast_canvas.draw()
|
|
||||||
|
|
||||||
def init_accuracy_chart(self):
|
def init_accuracy_chart(self):
|
||||||
"""初始化色准图表 - 固定大小,居中显示"""
|
"""转发到 app.views.chart_frame.init_accuracy_chart(Step 3 重构)"""
|
||||||
container = ttk.Frame(self.accuracy_chart_frame)
|
return _cf_init_accuracy_chart(self)
|
||||||
container.pack(expand=True)
|
|
||||||
|
|
||||||
self.accuracy_fig = plt.Figure(
|
|
||||||
figsize=(10, 6),
|
|
||||||
dpi=100,
|
|
||||||
tight_layout=False,
|
|
||||||
)
|
|
||||||
self.accuracy_canvas = FigureCanvasTkAgg(self.accuracy_fig, master=container)
|
|
||||||
|
|
||||||
canvas_widget = self.accuracy_canvas.get_tk_widget()
|
|
||||||
canvas_widget.pack()
|
|
||||||
|
|
||||||
canvas_widget.config(width=1000, height=600)
|
|
||||||
canvas_widget.pack_propagate(False)
|
|
||||||
|
|
||||||
self.accuracy_ax = self.accuracy_fig.add_subplot(111)
|
|
||||||
self.accuracy_ax.set_xlim(0, 1)
|
|
||||||
self.accuracy_ax.set_ylim(0, 1)
|
|
||||||
self.accuracy_ax.axis("off")
|
|
||||||
|
|
||||||
# 调整标题位置
|
|
||||||
self.accuracy_fig.suptitle("色准测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
self.accuracy_fig.subplots_adjust(
|
|
||||||
left=0.05,
|
|
||||||
right=0.95,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.05,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.accuracy_canvas.draw()
|
|
||||||
|
|
||||||
def clear_chart(self):
|
def clear_chart(self):
|
||||||
"""清空所有图表"""
|
"""转发到 app.views.chart_frame.clear_chart(Step 3 重构)"""
|
||||||
|
return _cf_clear_chart(self)
|
||||||
# ========== 1. 清空色域图表 ==========
|
|
||||||
if hasattr(self, "gamut_ax_xy") and hasattr(self, "gamut_ax_uv"):
|
|
||||||
# 清空XY图
|
|
||||||
self.gamut_ax_xy.clear()
|
|
||||||
self.gamut_ax_xy.set_xlim(0, 600)
|
|
||||||
self.gamut_ax_xy.set_ylim(600, 0)
|
|
||||||
self.gamut_ax_xy.axis("off")
|
|
||||||
self.gamut_ax_xy.set_clip_on(False)
|
|
||||||
|
|
||||||
# 清空UV图
|
|
||||||
self.gamut_ax_uv.clear()
|
|
||||||
self.gamut_ax_uv.set_xlim(0, 600)
|
|
||||||
self.gamut_ax_uv.set_ylim(600, 0)
|
|
||||||
self.gamut_ax_uv.axis("off")
|
|
||||||
self.gamut_ax_uv.set_clip_on(False)
|
|
||||||
|
|
||||||
self.gamut_fig.suptitle("色域测试", fontsize=12, y=0.98)
|
|
||||||
self.gamut_canvas.draw()
|
|
||||||
|
|
||||||
# ========== 2. 清空Gamma图表(4列 + 通用说明)==========
|
|
||||||
if hasattr(self, "gamma_ax") and hasattr(self, "gamma_table_ax"):
|
|
||||||
# 清空左侧曲线
|
|
||||||
self.gamma_ax.clear()
|
|
||||||
self.gamma_ax.set_xlim(0, 105)
|
|
||||||
self.gamma_ax.set_ylim(0, 1.1)
|
|
||||||
self.gamma_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
|
||||||
self.gamma_ax.set_ylabel("L_bar", fontsize=10)
|
|
||||||
self.gamma_ax.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.gamma_ax.tick_params(labelsize=9)
|
|
||||||
|
|
||||||
# 左侧提示
|
|
||||||
self.gamma_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
"等待测试数据...\n\n"
|
|
||||||
"将显示:\n"
|
|
||||||
"• 实测曲线 (蓝色)\n"
|
|
||||||
"• 理想 Gamma 曲线 (红色)\n\n"
|
|
||||||
"Gamma 值由测试配置决定",
|
|
||||||
ha="center",
|
|
||||||
va="center",
|
|
||||||
fontsize=10,
|
|
||||||
color="gray",
|
|
||||||
transform=self.gamma_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=1",
|
|
||||||
facecolor="white",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 清空右侧表格
|
|
||||||
self.gamma_table_ax.clear()
|
|
||||||
self.gamma_table_ax.axis("off")
|
|
||||||
|
|
||||||
# 4列表格
|
|
||||||
table_data = [
|
|
||||||
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "Gamma"],
|
|
||||||
["0%", "--", "--", "--"],
|
|
||||||
["10%", "--", "--", "--"],
|
|
||||||
["20%", "--", "--", "--"],
|
|
||||||
["30%", "--", "--", "--"],
|
|
||||||
["40%", "--", "--", "--"],
|
|
||||||
["50%", "--", "--", "--"],
|
|
||||||
["60%", "--", "--", "--"],
|
|
||||||
["70%", "--", "--", "--"],
|
|
||||||
["80%", "--", "--", "--"],
|
|
||||||
["90%", "--", "--", "--"],
|
|
||||||
["100%", "--", "--", "--"],
|
|
||||||
]
|
|
||||||
|
|
||||||
table = self.gamma_table_ax.table(
|
|
||||||
cellText=table_data,
|
|
||||||
cellLoc="center",
|
|
||||||
loc="center",
|
|
||||||
colWidths=[0.18, 0.28, 0.27, 0.27],
|
|
||||||
)
|
|
||||||
|
|
||||||
table.auto_set_font_size(False)
|
|
||||||
table.set_fontsize(7.5)
|
|
||||||
table.scale(1, 1.5)
|
|
||||||
|
|
||||||
# 表头样式
|
|
||||||
for i in range(4):
|
|
||||||
cell = table[(0, i)]
|
|
||||||
cell.set_facecolor("#4472C4")
|
|
||||||
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
|
||||||
|
|
||||||
# 数据行交替颜色
|
|
||||||
for i in range(1, len(table_data)):
|
|
||||||
for j in range(4):
|
|
||||||
cell = table[(i, j)]
|
|
||||||
if i % 2 == 0:
|
|
||||||
cell.set_facecolor("#E7E6E6")
|
|
||||||
else:
|
|
||||||
cell.set_facecolor("#FFFFFF")
|
|
||||||
|
|
||||||
# 底部说明
|
|
||||||
self.gamma_table_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.02,
|
|
||||||
"表格说明:\n"
|
|
||||||
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
|
||||||
"• L_bar: 归一化亮度 (0-1)\n"
|
|
||||||
"• Gamma: 实际 Gamma 值",
|
|
||||||
ha="center",
|
|
||||||
va="bottom",
|
|
||||||
fontsize=7,
|
|
||||||
color="gray",
|
|
||||||
transform=self.gamma_table_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=0.5",
|
|
||||||
facecolor="lightyellow",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.gamma_fig.suptitle("Gamma曲线 + 数据表格", fontsize=12, y=0.98)
|
|
||||||
self.gamma_canvas.draw()
|
|
||||||
|
|
||||||
# ========== 3. 清空EOTF图表(4列)==========
|
|
||||||
if hasattr(self, "eotf_ax") and hasattr(self, "eotf_table_ax"):
|
|
||||||
# 清空左侧曲线
|
|
||||||
self.eotf_ax.clear()
|
|
||||||
self.eotf_ax.set_xlim(0, 105)
|
|
||||||
self.eotf_ax.set_ylim(0, 1.1)
|
|
||||||
self.eotf_ax.set_xlabel("灰阶 (%)", fontsize=10)
|
|
||||||
self.eotf_ax.set_ylabel("L_bar (归一化亮度)", fontsize=10)
|
|
||||||
self.eotf_ax.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.eotf_ax.tick_params(labelsize=9)
|
|
||||||
|
|
||||||
# 左侧提示
|
|
||||||
self.eotf_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
"等待测试数据...\n\n将显示:\n• 实测 EOTF 曲线 (蓝色)\n• 理想 PQ 曲线 (红色)",
|
|
||||||
ha="center",
|
|
||||||
va="center",
|
|
||||||
fontsize=11,
|
|
||||||
color="gray",
|
|
||||||
transform=self.eotf_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=1",
|
|
||||||
facecolor="white",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
# 清空右侧表格
|
|
||||||
self.eotf_table_ax.clear()
|
|
||||||
self.eotf_table_ax.axis("off")
|
|
||||||
|
|
||||||
# 4列表格
|
|
||||||
table_data = [
|
|
||||||
["灰阶", "实测亮度\n(cd/m²)", "L_bar\n(计算)", "EOTF γ"],
|
|
||||||
["0%", "--", "--", "--"],
|
|
||||||
["10%", "--", "--", "--"],
|
|
||||||
["20%", "--", "--", "--"],
|
|
||||||
["30%", "--", "--", "--"],
|
|
||||||
["40%", "--", "--", "--"],
|
|
||||||
["50%", "--", "--", "--"],
|
|
||||||
["60%", "--", "--", "--"],
|
|
||||||
["70%", "--", "--", "--"],
|
|
||||||
["80%", "--", "--", "--"],
|
|
||||||
["90%", "--", "--", "--"],
|
|
||||||
["100%", "--", "--", "--"],
|
|
||||||
]
|
|
||||||
|
|
||||||
table = self.eotf_table_ax.table(
|
|
||||||
cellText=table_data,
|
|
||||||
cellLoc="center",
|
|
||||||
loc="center",
|
|
||||||
colWidths=[0.18, 0.28, 0.27, 0.27],
|
|
||||||
)
|
|
||||||
|
|
||||||
table.auto_set_font_size(False)
|
|
||||||
table.set_fontsize(7.5)
|
|
||||||
table.scale(1, 1.5)
|
|
||||||
|
|
||||||
# 表头样式
|
|
||||||
for i in range(4):
|
|
||||||
cell = table[(0, i)]
|
|
||||||
cell.set_facecolor("#4472C4")
|
|
||||||
cell.set_text_props(weight="bold", color="white", fontsize=7)
|
|
||||||
|
|
||||||
# 数据行交替颜色
|
|
||||||
for i in range(1, len(table_data)):
|
|
||||||
for j in range(4):
|
|
||||||
cell = table[(i, j)]
|
|
||||||
if i % 2 == 0:
|
|
||||||
cell.set_facecolor("#E7E6E6")
|
|
||||||
else:
|
|
||||||
cell.set_facecolor("#FFFFFF")
|
|
||||||
|
|
||||||
# 底部说明
|
|
||||||
self.eotf_table_ax.text(
|
|
||||||
0.5,
|
|
||||||
0.02,
|
|
||||||
"表格说明:\n"
|
|
||||||
"• 实测亮度: 色度计测量值 (cd/m²)\n"
|
|
||||||
"• L_bar: 归一化亮度 (0-1)\n"
|
|
||||||
"• EOTF γ: HDR 实际 Gamma 值",
|
|
||||||
ha="center",
|
|
||||||
va="bottom",
|
|
||||||
fontsize=7,
|
|
||||||
color="gray",
|
|
||||||
transform=self.eotf_table_ax.transAxes,
|
|
||||||
bbox=dict(
|
|
||||||
boxstyle="round,pad=0.5",
|
|
||||||
facecolor="lightyellow",
|
|
||||||
edgecolor="gray",
|
|
||||||
alpha=0.8,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.eotf_fig.suptitle("EOTF 曲线 + 数据表格", fontsize=12, y=0.98)
|
|
||||||
self.eotf_canvas.draw()
|
|
||||||
|
|
||||||
# ========== 4. 清空色度图表 ==========
|
|
||||||
if hasattr(self, "cct_ax1") and hasattr(self, "cct_ax2"):
|
|
||||||
# 上图:x coordinates
|
|
||||||
self.cct_ax1.clear()
|
|
||||||
self.cct_ax1.set_xlabel("灰阶 (%)", fontsize=9)
|
|
||||||
self.cct_ax1.set_ylabel("CIE x", fontsize=9)
|
|
||||||
self.cct_ax1.set_xlim(0, 105)
|
|
||||||
self.cct_ax1.set_ylim(0.25, 0.35)
|
|
||||||
self.cct_ax1.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.cct_ax1.tick_params(labelsize=8)
|
|
||||||
|
|
||||||
# 下图:y coordinates
|
|
||||||
self.cct_ax2.clear()
|
|
||||||
self.cct_ax2.set_xlabel("灰阶 (%)", fontsize=9)
|
|
||||||
self.cct_ax2.set_ylabel("CIE y", fontsize=9)
|
|
||||||
self.cct_ax2.set_xlim(0, 105)
|
|
||||||
self.cct_ax2.set_ylim(0.25, 0.35)
|
|
||||||
self.cct_ax2.grid(True, linestyle="--", alpha=0.3)
|
|
||||||
self.cct_ax2.tick_params(labelsize=8)
|
|
||||||
|
|
||||||
self.cct_fig.suptitle("色度一致性测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
# 重置布局
|
|
||||||
self.cct_fig.subplots_adjust(
|
|
||||||
left=0.12,
|
|
||||||
right=0.88,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.08,
|
|
||||||
hspace=0.25,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.cct_canvas.draw()
|
|
||||||
|
|
||||||
# ========== 5. 清空对比度图表 ==========
|
|
||||||
if hasattr(self, "contrast_ax"):
|
|
||||||
self.contrast_ax.clear()
|
|
||||||
self.contrast_ax.set_xlim(0, 1)
|
|
||||||
self.contrast_ax.set_ylim(0, 1)
|
|
||||||
self.contrast_ax.axis("off")
|
|
||||||
|
|
||||||
self.contrast_fig.suptitle("对比度测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
# 重置布局
|
|
||||||
self.contrast_fig.subplots_adjust(
|
|
||||||
left=0.02,
|
|
||||||
right=0.98,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.02,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.contrast_canvas.draw()
|
|
||||||
|
|
||||||
# ========== 6. 清空色准图表 ==========
|
|
||||||
if hasattr(self, "accuracy_ax"):
|
|
||||||
self.accuracy_ax.clear()
|
|
||||||
self.accuracy_ax.set_xlim(0, 1)
|
|
||||||
self.accuracy_ax.set_ylim(0, 1)
|
|
||||||
self.accuracy_ax.axis("off")
|
|
||||||
|
|
||||||
# 标题
|
|
||||||
self.accuracy_fig.suptitle("色准测试", fontsize=12, y=0.985)
|
|
||||||
|
|
||||||
# 重置布局
|
|
||||||
self.accuracy_fig.subplots_adjust(
|
|
||||||
left=0.05,
|
|
||||||
right=0.95,
|
|
||||||
top=0.90,
|
|
||||||
bottom=0.05,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.accuracy_canvas.draw()
|
|
||||||
|
|
||||||
def create_floating_config_panel(self):
|
def create_floating_config_panel(self):
|
||||||
"""创建右上角悬浮配置框"""
|
"""创建右上角悬浮配置框"""
|
||||||
cf = CollapsingFrame(self.control_frame_top)
|
cf = CollapsingFrame(self.control_frame_top)
|
||||||
@@ -1477,7 +849,7 @@ class PQAutomationApp:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# 3. 跳转到色度图Tab
|
# 3. 跳转到色度图Tab
|
||||||
self.chart_notebook.select(2) # ← 色度图是第3个Tab(索引2)
|
self.chart_notebook.select(self.cct_chart_frame)
|
||||||
self.root.update_idletasks()
|
self.root.update_idletasks()
|
||||||
|
|
||||||
# 4. 检查是否有数据
|
# 4. 检查是否有数据
|
||||||
@@ -1538,7 +910,7 @@ class PQAutomationApp:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# 2. 跳转到色域图Tab
|
# 2. 跳转到色域图Tab
|
||||||
self.chart_notebook.select(0) # 色域图是第1个Tab
|
self.chart_notebook.select(self.gamut_chart_frame)
|
||||||
self.root.update_idletasks()
|
self.root.update_idletasks()
|
||||||
|
|
||||||
# 3. 检查是否有数据
|
# 3. 检查是否有数据
|
||||||
@@ -1854,83 +1226,8 @@ class PQAutomationApp:
|
|||||||
self.update_chart_tabs_state()
|
self.update_chart_tabs_state()
|
||||||
|
|
||||||
def update_chart_tabs_state(self):
|
def update_chart_tabs_state(self):
|
||||||
"""根据测试项目复选框状态更新图表Tab的启用/禁用"""
|
"""转发到 app.views.chart_frame.update_chart_tabs_state(Step 3 重构)"""
|
||||||
if not hasattr(self, "chart_notebook"):
|
return _cf_update_chart_tabs_state(self)
|
||||||
return
|
|
||||||
|
|
||||||
selected_items = self.get_selected_test_items()
|
|
||||||
current_test_type = self.config.current_test_type
|
|
||||||
|
|
||||||
# 检查5个独立图表的选中状态
|
|
||||||
gamut_selected = "gamut" in selected_items
|
|
||||||
gamma_selected = "gamma" in selected_items or "eotf" in selected_items
|
|
||||||
cct_selected = "cct" in selected_items
|
|
||||||
contrast_selected = "contrast" in selected_items
|
|
||||||
accuracy_selected = "accuracy" in selected_items
|
|
||||||
|
|
||||||
# 屏模组测试时,强制隐藏色准 Tab
|
|
||||||
if current_test_type == "screen_module":
|
|
||||||
accuracy_selected = False
|
|
||||||
|
|
||||||
try:
|
|
||||||
# 获取当前所有 Tab
|
|
||||||
current_tabs = self.chart_notebook.tabs()
|
|
||||||
current_tab_set = set(current_tabs)
|
|
||||||
|
|
||||||
gamut_tab_id = str(self.gamut_chart_frame)
|
|
||||||
gamma_tab_id = str(self.gamma_chart_frame)
|
|
||||||
eotf_tab_id = str(self.eotf_chart_frame)
|
|
||||||
cct_tab_id = str(self.cct_chart_frame)
|
|
||||||
contrast_tab_id = str(self.contrast_chart_frame)
|
|
||||||
accuracy_tab_id = str(self.accuracy_chart_frame)
|
|
||||||
|
|
||||||
# ========== 控制前4个固定 Tab ==========
|
|
||||||
if gamut_tab_id in current_tab_set:
|
|
||||||
self.chart_notebook.tab(
|
|
||||||
gamut_tab_id, state="normal" if gamut_selected else "disabled"
|
|
||||||
)
|
|
||||||
|
|
||||||
if gamma_tab_id in current_tab_set:
|
|
||||||
self.chart_notebook.tab(
|
|
||||||
gamma_tab_id, state="normal" if gamma_selected else "disabled"
|
|
||||||
)
|
|
||||||
elif eotf_tab_id in current_tab_set:
|
|
||||||
self.chart_notebook.tab(
|
|
||||||
eotf_tab_id, state="normal" if gamma_selected else "disabled"
|
|
||||||
)
|
|
||||||
|
|
||||||
if cct_tab_id in current_tab_set:
|
|
||||||
self.chart_notebook.tab(
|
|
||||||
cct_tab_id, state="normal" if cct_selected else "disabled"
|
|
||||||
)
|
|
||||||
|
|
||||||
if contrast_tab_id in current_tab_set:
|
|
||||||
self.chart_notebook.tab(
|
|
||||||
contrast_tab_id,
|
|
||||||
state="normal" if contrast_selected else "disabled",
|
|
||||||
)
|
|
||||||
|
|
||||||
# ========== 控制色准 Tab(动态添加/移除)==========
|
|
||||||
accuracy_tab_exists = accuracy_tab_id in current_tab_set
|
|
||||||
|
|
||||||
if accuracy_selected and not accuracy_tab_exists:
|
|
||||||
# 需要显示色准,但当前没有 → 添加
|
|
||||||
self.chart_notebook.add(self.accuracy_chart_frame, text="色准")
|
|
||||||
self.chart_notebook.tab(accuracy_tab_id, state="normal")
|
|
||||||
self.log_gui.log("✓ 色准 Tab 已显示")
|
|
||||||
|
|
||||||
elif accuracy_selected and accuracy_tab_exists:
|
|
||||||
# 需要显示色准,且已存在 → 启用
|
|
||||||
self.chart_notebook.tab(accuracy_tab_id, state="normal")
|
|
||||||
|
|
||||||
elif not accuracy_selected and accuracy_tab_exists:
|
|
||||||
# 不需要显示色准,但存在 → 移除
|
|
||||||
self.chart_notebook.forget(self.accuracy_chart_frame)
|
|
||||||
self.log_gui.log("✓ 色准 Tab 已隐藏")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.log_gui.log(f"更新Tab状态失败: {str(e)}")
|
|
||||||
|
|
||||||
def get_test_type_display_name(self, test_type):
|
def get_test_type_display_name(self, test_type):
|
||||||
"""获取测试类型的显示名称"""
|
"""获取测试类型的显示名称"""
|
||||||
display_names = {
|
display_names = {
|
||||||
@@ -3336,74 +2633,11 @@ class PQAutomationApp:
|
|||||||
self.show_panel("log")
|
self.show_panel("log")
|
||||||
|
|
||||||
def create_result_chart_frame(self):
|
def create_result_chart_frame(self):
|
||||||
"""创建结果图表区域 - 6个独立Tab(Gamma 和 EOTF 分离)"""
|
"""转发到 app.views.chart_frame.create_result_chart_frame(Step 3 重构)"""
|
||||||
# 创建Notebook用于图表切换
|
return _cf_create_result_chart_frame(self)
|
||||||
self.chart_notebook = ttk.Notebook(self.result_frame)
|
|
||||||
self.chart_notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
|
|
||||||
|
|
||||||
# ========== 创建6个独立的Tab页面 ==========
|
|
||||||
# 1. 色域图页面
|
|
||||||
self.gamut_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 2. Gamma图页面(SDR/屏模组使用)
|
|
||||||
self.gamma_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 3. EOTF图页面(HDR专用)
|
|
||||||
self.eotf_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 4. 色度一致性页面
|
|
||||||
self.cct_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 5. 对比度页面
|
|
||||||
self.contrast_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 6. 色准页面
|
|
||||||
self.accuracy_chart_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# 7. 客户模板结果页面
|
|
||||||
self.custom_template_tab_frame = ttk.Frame(self.chart_notebook)
|
|
||||||
|
|
||||||
# ========== 添加到Notebook(初始只添加前5个)==========
|
|
||||||
self.chart_notebook.add(self.gamut_chart_frame, text="色域图")
|
|
||||||
self.chart_notebook.add(self.gamma_chart_frame, text="Gamma曲线")
|
|
||||||
# ← EOTF 不添加,由 change_test_type() 动态控制
|
|
||||||
self.chart_notebook.add(self.cct_chart_frame, text="色度一致性")
|
|
||||||
self.chart_notebook.add(self.contrast_chart_frame, text="对比度")
|
|
||||||
self.chart_notebook.add(self.accuracy_chart_frame, text="色准")
|
|
||||||
|
|
||||||
# 初始化六个独立的图表
|
|
||||||
self.init_gamut_chart()
|
|
||||||
self.init_gamma_chart()
|
|
||||||
self.init_eotf_chart()
|
|
||||||
self.init_cct_chart()
|
|
||||||
self.init_contrast_chart()
|
|
||||||
self.init_accuracy_chart()
|
|
||||||
|
|
||||||
# 绑定Tab切换事件
|
|
||||||
self.chart_notebook.bind("<<NotebookTabChanged>>", self.on_chart_tab_changed)
|
|
||||||
|
|
||||||
# ==================== ✅ 在图表下方创建单步调试面板 ====================
|
|
||||||
self.debug_container = ttk.LabelFrame(
|
|
||||||
self.result_frame, # ← 放在 result_frame 内,图表正下方
|
|
||||||
text="🔧 单步调试",
|
|
||||||
padding=10,
|
|
||||||
)
|
|
||||||
# 默认不显示
|
|
||||||
|
|
||||||
# 创建单步调试面板实例
|
|
||||||
self.debug_panel = PQDebugPanel(self.debug_container, self)
|
|
||||||
|
|
||||||
self.log_gui.log("✓ 单步调试面板已创建(放在测试结果图表下方)")
|
|
||||||
|
|
||||||
def on_chart_tab_changed(self, event):
|
def on_chart_tab_changed(self, event):
|
||||||
"""Tab切换时的事件处理"""
|
"""转发到 app.views.chart_frame.on_chart_tab_changed(Step 3 重构)"""
|
||||||
try:
|
return _cf_on_chart_tab_changed(self, event)
|
||||||
self._last_tab_index = self.chart_notebook.index(
|
|
||||||
self.chart_notebook.select()
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
self.log_gui.log(f"Tab切换事件处理失败: {str(e)}")
|
|
||||||
|
|
||||||
def change_test_type(self, test_type):
|
def change_test_type(self, test_type):
|
||||||
"""切换测试类型"""
|
"""切换测试类型"""
|
||||||
# 切换测试类型时,自动隐藏日志面板和 Local Dimming 面板
|
# 切换测试类型时,自动隐藏日志面板和 Local Dimming 面板
|
||||||
@@ -3810,7 +3044,7 @@ class PQAutomationApp:
|
|||||||
# ========== 5.2.5 跳转到色域图Tab(第一个Tab)==========
|
# ========== 5.2.5 跳转到色域图Tab(第一个Tab)==========
|
||||||
try:
|
try:
|
||||||
if hasattr(self, "chart_notebook"):
|
if hasattr(self, "chart_notebook"):
|
||||||
self.chart_notebook.select(0) # ← 选中第一个Tab(色域图)
|
self.chart_notebook.select(self.gamut_chart_frame)
|
||||||
self.root.update_idletasks() # ← 刷新界面
|
self.root.update_idletasks() # ← 刷新界面
|
||||||
self.log_gui.log("✓ 已跳转到色域图界面")
|
self.log_gui.log("✓ 已跳转到色域图界面")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user