@@ -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 ) } " )