修改色域画图及重绘方式

This commit is contained in:
xinzhu.yin
2026-05-18 15:57:11 +08:00
parent 9371defb6e
commit d7495734a5
9 changed files with 900 additions and 540 deletions

View File

@@ -136,12 +136,15 @@ def create_custom_template_result_panel(self):
label="单步测试",
command=self.start_custom_row_single_step,
)
# self.custom_result_menu.add_separator()
# self.custom_result_menu.add_command(
# label="单步测试",
# command=self.fill_custom_result_test_data,
# )
self.custom_result_menu.add_separator()
self.custom_result_menu.add_command(
label="生成模板",
command=self.export_custom_template_excel,
)
self.custom_result_menu.add_command(
label="生成图表",
command=self.export_custom_template_charts,
)
self.custom_result_tree.bind("<Button-3>", self.show_custom_result_context_menu)
table_container.grid_rowconfigure(0, weight=1)
@@ -181,6 +184,14 @@ def show_custom_result_context_menu(self, event):
1,
state=("normal" if can_single_step else "disabled"),
)
self.custom_result_menu.entryconfigure(
3,
state=("normal" if has_rows else "disabled"),
)
self.custom_result_menu.entryconfigure(
4,
state=("normal" if has_rows else "disabled"),
)
self.custom_result_menu.tk_popup(event.x_root, event.y_root)
finally:
self.custom_result_menu.grab_release()
@@ -614,3 +625,290 @@ def update_custom_button_visibility(self):
# self.status_var.set("已填充 147 行客户模板测试数据")
# if hasattr(self, "log_gui"):
# self.log_gui.log("已填充 147 行客户模板测试数据", level="success")
def export_custom_template_excel(self):
"""将客户模板结果表导出为 Excel 文件14 列完整数据)"""
if not hasattr(self, "custom_result_tree"):
return
items = self.custom_result_tree.get_children()
if not items:
messagebox.showinfo("提示", "当前没有可导出的数据")
return
import datetime
from tkinter import filedialog
default_name = (
f"客户模板结果_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
)
save_path = filedialog.asksaveasfilename(
title="保存客户模板 Excel 报告",
defaultextension=".xlsx",
filetypes=[("Excel 文件", "*.xlsx")],
initialfile=default_name,
)
if not save_path:
return
try:
from openpyxl import Workbook
from openpyxl.styles import Alignment, Border, Font, PatternFill, Side
wb = Workbook()
ws = wb.active
ws.title = "客户模板测试结果"
columns = tuple(self.custom_result_tree["columns"])
num_cols = len(columns)
# 列字母辅助A-N共 14 列,全在单字母范围内)
def col_letter(idx_1based):
return chr(64 + idx_1based)
last_col = col_letter(num_cols)
# ---- 标题行 ----
ws.merge_cells(f"A1:{last_col}1")
ws["A1"] = "客户模板测试结果"
ws["A1"].font = Font(name="微软雅黑", size=16, bold=True, color="FFFFFF")
ws["A1"].fill = PatternFill(
start_color="4472C4", end_color="4472C4", fill_type="solid"
)
ws["A1"].alignment = Alignment(horizontal="center", vertical="center")
ws.row_dimensions[1].height = 35
# 写入测试时间
ws.merge_cells(f"A2:{last_col}2")
ws["A2"] = (
f"测试时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
)
ws["A2"].font = Font(name="微软雅黑", size=10, color="CCCCCC")
ws["A2"].fill = PatternFill(
start_color="2F2F2F", end_color="2F2F2F", fill_type="solid"
)
ws["A2"].alignment = Alignment(horizontal="left", vertical="center")
ws.row_dimensions[2].height = 20
# ---- 表头行 ----
thin = Side(style="thin")
border = Border(left=thin, right=thin, top=thin, bottom=thin)
header_font = Font(name="微软雅黑", size=10, bold=True, color="FFFFFF")
header_fill = PatternFill(
start_color="70AD47", end_color="70AD47", fill_type="solid"
)
header_align = Alignment(
horizontal="center", vertical="center", wrap_text=True
)
for col_idx, col_name in enumerate(columns, start=1):
cell = ws.cell(row=3, column=col_idx, value=col_name)
cell.font = header_font
cell.fill = header_fill
cell.alignment = header_align
cell.border = border
ws.row_dimensions[3].height = 22
# ---- 数据行 ----
data_font = Font(name="微软雅黑", size=10)
data_align = Alignment(horizontal="center", vertical="center")
# 数值列(跳过 Pattern 和 No.)以 4 位小数格式输出
numeric_col_indices = set(range(2, num_cols))
for row_offset, item in enumerate(items):
row_num = 4 + row_offset
values = self.custom_result_tree.item(item, "values")
for col_idx, value in enumerate(values, start=1):
cell = ws.cell(row=row_num, column=col_idx)
cell.font = data_font
cell.alignment = data_align
cell.border = border
# 占位符保持文本,非占位符数值列尝试转为浮点数
if (
col_idx - 1 in numeric_col_indices
and str(value) not in ("---", "--", "")
):
try:
cell.value = float(value)
cell.number_format = "0.0000"
except (ValueError, TypeError):
cell.value = value
else:
cell.value = value
ws.row_dimensions[row_num].height = 20
# ---- 列宽 ----
col_widths = {
"Pattern": 14,
"No.": 8,
"X": 11,
"Y": 11,
"Z": 11,
"x": 10,
"y": 10,
"Lv": 10,
"u'": 10,
"v'": 10,
"Tcp": 12,
"duv": 10,
"\u03bbd/\u03bbc": 12,
"Pe": 10,
}
for col_idx, col_name in enumerate(columns, start=1):
ws.column_dimensions[col_letter(col_idx)].width = col_widths.get(
col_name, 11
)
wb.save(save_path)
if hasattr(self, "status_var"):
self.status_var.set("已导出客户模板 Excel 报告")
if hasattr(self, "log_gui"):
self.log_gui.log(
f"已导出客户模板 Excel 报告: {save_path}", level="success"
)
messagebox.showinfo("成功", f"Excel 报告已保存到:\n{save_path}")
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"导出 Excel 失败: {str(e)}", level="error")
messagebox.showerror("错误", f"导出失败:{str(e)}")
def export_custom_template_charts(self):
"""生成客户模板图表xy 色度散点图 + Lv 亮度曲线图,保存为 PNG"""
if not hasattr(self, "custom_result_tree"):
return
items = self.custom_result_tree.get_children()
if not items:
messagebox.showinfo("提示", "当前没有可绘制的数据")
return
import datetime
from tkinter import filedialog
default_name = (
f"客户模板图表_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
)
save_path = filedialog.asksaveasfilename(
title="保存客户模板图表",
defaultextension=".png",
filetypes=[("PNG 图片", "*.png")],
initialfile=default_name,
)
if not save_path:
return
try:
import matplotlib.pyplot as plt
columns = tuple(self.custom_result_tree["columns"])
col_idx_map = {col: idx for idx, col in enumerate(columns)}
pattern_names, x_vals, y_vals, lv_vals = [], [], [], []
for item in items:
vals = self.custom_result_tree.item(item, "values")
pattern_names.append(str(vals[col_idx_map.get("Pattern", 0)]))
for container, key, fallback in (
(x_vals, "x", 5),
(y_vals, "y", 6),
(lv_vals, "Lv", 7),
):
raw = vals[col_idx_map.get(key, fallback)]
try:
v = float(raw)
container.append(v if np.isfinite(v) and v > -99999998 else None)
except (ValueError, TypeError):
container.append(None)
# ---- 绘图 ----
fig, (ax_xy, ax_lv) = plt.subplots(
1, 2, figsize=(16, 7), facecolor="#1a1a2e"
)
# ── 左图xy 色度散点图 ──
ax_xy.set_facecolor("#0f0f23")
ax_xy.set_xlim(0, 0.8)
ax_xy.set_ylim(0, 0.9)
ax_xy.set_xlabel("x", color="#cccccc", fontsize=11)
ax_xy.set_ylabel("y", color="#cccccc", fontsize=11)
ax_xy.set_title("xy 色度图", color="#ffffff", fontsize=13, fontweight="bold")
ax_xy.tick_params(colors="#aaaaaa", which="both")
for spine in ax_xy.spines.values():
spine.set_color("#444444")
ax_xy.grid(color="#333333", linestyle="--", linewidth=0.5, alpha=0.7)
# D65 白点标注
ax_xy.scatter(
[0.3127], [0.3290],
c="#ffffff", s=100, zorder=5,
marker="+", linewidths=2, label="D65",
)
valid_pairs = [
(x, y, i)
for i, (x, y) in enumerate(zip(x_vals, y_vals))
if x is not None and y is not None
]
if valid_pairs:
xs, ys, idxs = zip(*valid_pairs)
sc = ax_xy.scatter(
xs, ys,
c=idxs,
cmap="plasma",
s=60, zorder=4,
edgecolors="#cccccc", linewidths=0.5, alpha=0.9,
)
cbar = fig.colorbar(sc, ax=ax_xy, pad=0.01)
cbar.set_label("测量序号", color="#cccccc", fontsize=10)
cbar.ax.yaxis.set_tick_params(color="#aaaaaa")
plt.setp(cbar.ax.yaxis.get_ticklabels(), color="#aaaaaa")
ax_xy.legend(
fontsize=9,
facecolor="#2a2a3e",
edgecolor="#555555",
labelcolor="#cccccc",
)
# ── 右图Lv 亮度曲线 ──
ax_lv.set_facecolor("#0f0f23")
ax_lv.set_title(
"Lv 亮度曲线", color="#ffffff", fontsize=13, fontweight="bold"
)
ax_lv.set_xlabel("测量序号", color="#cccccc", fontsize=11)
ax_lv.set_ylabel("Lv (cd/m²)", color="#cccccc", fontsize=11)
ax_lv.tick_params(colors="#aaaaaa", which="both")
for spine in ax_lv.spines.values():
spine.set_color("#444444")
ax_lv.grid(color="#333333", linestyle="--", linewidth=0.5, alpha=0.7)
valid_lv = [(i + 1, lv) for i, lv in enumerate(lv_vals) if lv is not None]
if valid_lv:
seq, lvs = zip(*valid_lv)
ax_lv.plot(
seq, lvs,
color="#4fc3f7", linewidth=1.5,
marker="o", markersize=4,
markerfacecolor="#ff8c00", markeredgecolor="#ff8c00",
)
ax_lv.fill_between(seq, lvs, alpha=0.15, color="#4fc3f7")
plt.tight_layout(pad=2.0)
fig.savefig(save_path, dpi=200, bbox_inches="tight",
facecolor=fig.get_facecolor())
plt.close(fig)
if hasattr(self, "status_var"):
self.status_var.set("已生成客户模板图表")
if hasattr(self, "log_gui"):
self.log_gui.log(
f"已生成客户模板图表: {save_path}", level="success"
)
messagebox.showinfo("成功", f"图表已保存到:\n{save_path}")
except Exception as e:
if hasattr(self, "log_gui"):
self.log_gui.log(f"生成图表失败: {str(e)}", level="error")
messagebox.showerror("错误", f"生成图表失败:{str(e)}")