添加Local Dimming图像
This commit is contained in:
@@ -31,6 +31,9 @@ if TYPE_CHECKING:
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
DEFAULT_WINDOW_PERCENTAGES = [1, 2, 5, 10, 18, 25, 50, 75, 100]
|
DEFAULT_WINDOW_PERCENTAGES = [1, 2, 5, 10, 18, 25, 50, 75, 100]
|
||||||
|
DEFAULT_CHESSBOARD_GRID = 5
|
||||||
|
INSTANT_PEAK_WINDOW_PERCENTAGE = 10
|
||||||
|
INSTANT_PEAK_CAPTURE_DELAY = 0.5
|
||||||
|
|
||||||
_TEMP_DIR = None
|
_TEMP_DIR = None
|
||||||
_IMAGE_CACHE = {} # {(width, height, percentage): file_path}
|
_IMAGE_CACHE = {} # {(width, height, percentage): file_path}
|
||||||
@@ -89,100 +92,172 @@ def _ensure_window_image(width, height, percentage):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_solid_image(width, height, rgb, name):
|
||||||
|
"""生成或复用纯色 PNG 文件,返回路径。"""
|
||||||
|
rgb = tuple(int(v) for v in rgb)
|
||||||
|
key = ("solid", width, height, rgb)
|
||||||
|
cached = _IMAGE_CACHE.get(key)
|
||||||
|
if cached and os.path.exists(cached):
|
||||||
|
return cached
|
||||||
|
|
||||||
|
arr = np.zeros((height, width, 3), dtype=np.uint8)
|
||||||
|
arr[:, :] = rgb
|
||||||
|
path = os.path.join(_get_temp_dir(), f"{name}_{width}x{height}.png")
|
||||||
|
Image.fromarray(arr, mode="RGB").save(path, format="PNG")
|
||||||
|
_IMAGE_CACHE[key] = path
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def _make_checkerboard_image_array(width, height, grid_size, center_white):
|
||||||
|
"""生成棋盘格图像,保证中心块可切换黑/白。"""
|
||||||
|
image = np.zeros((height, width, 3), dtype=np.uint8)
|
||||||
|
y_edges = np.linspace(0, height, grid_size + 1, dtype=int)
|
||||||
|
x_edges = np.linspace(0, width, grid_size + 1, dtype=int)
|
||||||
|
center_index = grid_size // 2
|
||||||
|
|
||||||
|
for row in range(grid_size):
|
||||||
|
for col in range(grid_size):
|
||||||
|
block_is_white = (row + col) % 2 == 0
|
||||||
|
if not center_white:
|
||||||
|
block_is_white = not block_is_white
|
||||||
|
value = 255 if block_is_white else 0
|
||||||
|
image[
|
||||||
|
y_edges[row]:y_edges[row + 1],
|
||||||
|
x_edges[col]:x_edges[col + 1],
|
||||||
|
] = value
|
||||||
|
|
||||||
|
center_value = 255 if center_white else 0
|
||||||
|
image[
|
||||||
|
y_edges[center_index]:y_edges[center_index + 1],
|
||||||
|
x_edges[center_index]:x_edges[center_index + 1],
|
||||||
|
] = center_value
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
|
def _ensure_checkerboard_image(width, height, grid_size, center_white):
|
||||||
|
"""生成或复用棋盘格 PNG 文件,返回路径。"""
|
||||||
|
key = ("checkerboard", width, height, grid_size, center_white)
|
||||||
|
cached = _IMAGE_CACHE.get(key)
|
||||||
|
if cached and os.path.exists(cached):
|
||||||
|
return cached
|
||||||
|
|
||||||
|
arr = _make_checkerboard_image_array(width, height, grid_size, center_white)
|
||||||
|
center_name = "white_center" if center_white else "black_center"
|
||||||
|
path = os.path.join(
|
||||||
|
_get_temp_dir(),
|
||||||
|
f"checkerboard_{grid_size}x{grid_size}_{center_name}_{width}x{height}.png",
|
||||||
|
)
|
||||||
|
Image.fromarray(arr, mode="RGB").save(path, format="PNG")
|
||||||
|
_IMAGE_CACHE[key] = path
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def _build_ld_result_row(test_item, pattern_label, value, x="--", y="--"):
|
||||||
|
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
|
||||||
|
if isinstance(value, (int, float, np.floating)):
|
||||||
|
display_value = f"{float(value):.4f}"
|
||||||
|
else:
|
||||||
|
display_value = str(value)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"test_item": test_item,
|
||||||
|
"pattern": pattern_label,
|
||||||
|
"value": display_value,
|
||||||
|
"x": x if isinstance(x, str) else f"{x:.4f}",
|
||||||
|
"y": y if isinstance(y, str) else f"{y:.4f}",
|
||||||
|
"time": timestamp,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _measure_ld_row(self: "PQAutomationApp", test_item, pattern_label):
|
||||||
|
"""读取一次 CA410 数据并包装为表格行。"""
|
||||||
|
x, y, lv, _X, _Y, _Z = self.ca.readAllDisplay()
|
||||||
|
if lv is None:
|
||||||
|
raise RuntimeError(f"{pattern_label} 采集失败")
|
||||||
|
return _build_ld_result_row(test_item, pattern_label, lv, x, y), lv
|
||||||
|
|
||||||
|
|
||||||
|
def _send_ld_image(self: "PQAutomationApp", image_path):
|
||||||
|
self.signal_service.send_image(image_path)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_ld_measurement_step(self: "PQAutomationApp", width, height, wait_time, step, log):
|
||||||
|
label = step["label"]
|
||||||
|
test_item = step["test_item"]
|
||||||
|
kind = step["kind"]
|
||||||
|
|
||||||
|
if kind == "window":
|
||||||
|
percentage = step["percentage"]
|
||||||
|
image_path = _ensure_window_image(width, height, percentage)
|
||||||
|
_send_ld_image(self, image_path)
|
||||||
|
settle_time = wait_time
|
||||||
|
elif kind == "black":
|
||||||
|
image_path = _ensure_solid_image(width, height, (0, 0, 0), "black")
|
||||||
|
_send_ld_image(self, image_path)
|
||||||
|
settle_time = wait_time
|
||||||
|
elif kind == "checkerboard":
|
||||||
|
image_path = _ensure_checkerboard_image(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
DEFAULT_CHESSBOARD_GRID,
|
||||||
|
step["center_white"],
|
||||||
|
)
|
||||||
|
_send_ld_image(self, image_path)
|
||||||
|
settle_time = wait_time
|
||||||
|
elif kind == "instant_peak":
|
||||||
|
black_image = _ensure_solid_image(width, height, (0, 0, 0), "black")
|
||||||
|
peak_image = _ensure_window_image(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
step["percentage"],
|
||||||
|
)
|
||||||
|
_send_ld_image(self, black_image)
|
||||||
|
log(f" 黑场预置 {wait_time:.1f} 秒", level="info")
|
||||||
|
time.sleep(wait_time)
|
||||||
|
_send_ld_image(self, peak_image)
|
||||||
|
settle_time = min(wait_time, INSTANT_PEAK_CAPTURE_DELAY)
|
||||||
|
else:
|
||||||
|
raise ValueError(f"未知 Local Dimming 测试步骤: {kind}")
|
||||||
|
|
||||||
|
log(f" 等待 {settle_time:.1f} 秒后采集...", level="info")
|
||||||
|
time.sleep(settle_time)
|
||||||
|
return _measure_ld_row(self, test_item, label)
|
||||||
|
|
||||||
|
|
||||||
|
def _set_current_ld_pattern(self: "PQAutomationApp", test_item, pattern_label, percentage=None):
|
||||||
|
self.current_ld_test_item = test_item
|
||||||
|
self.current_ld_pattern_label = pattern_label
|
||||||
|
self.current_ld_percentage = percentage
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# GUI 入口(绑定为 PQAutomationApp 方法)
|
# GUI 入口(绑定为 PQAutomationApp 方法)
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
def start_local_dimming_test(self: "PQAutomationApp"):
|
def start_local_dimming_test(self: "PQAutomationApp"):
|
||||||
"""开始 Local Dimming 测试。"""
|
"""Local Dimming 不再提供自动测试,保留接口仅提示用户使用手动模式。"""
|
||||||
if not self.ca or not self.signal_service.is_connected:
|
messagebox.showinfo("提示", "Local Dimming 请使用手动发送图案后再采集亮度")
|
||||||
messagebox.showerror("错误", "请先连接 CA410 和 UCD323")
|
|
||||||
return
|
|
||||||
|
|
||||||
self.ld_start_btn.config(state=tk.DISABLED)
|
|
||||||
self.ld_stop_btn.config(state=tk.NORMAL)
|
|
||||||
self.ld_save_btn.config(state=tk.DISABLED)
|
|
||||||
|
|
||||||
for item in self.ld_tree.get_children():
|
|
||||||
self.ld_tree.delete(item)
|
|
||||||
|
|
||||||
wait_time = float(self.ld_wait_time_var.get())
|
|
||||||
stop_event = threading.Event()
|
|
||||||
self.ld_stop_event = stop_event
|
|
||||||
|
|
||||||
def worker():
|
|
||||||
log = self.log_gui.log
|
|
||||||
log("=" * 60, level="separator")
|
|
||||||
log("开始 Local Dimming 测试", level="info")
|
|
||||||
log("=" * 60, level="separator")
|
|
||||||
|
|
||||||
width, height = self.signal_service.current_resolution()
|
|
||||||
total = len(DEFAULT_WINDOW_PERCENTAGES)
|
|
||||||
log(f" 分辨率: {width}x{height}", level="info")
|
|
||||||
log(f" 测试窗口: {DEFAULT_WINDOW_PERCENTAGES}", level="info")
|
|
||||||
log(f" 等待时间: {wait_time} 秒", level="info")
|
|
||||||
|
|
||||||
results = []
|
|
||||||
for i, percentage in enumerate(DEFAULT_WINDOW_PERCENTAGES, 1):
|
|
||||||
if stop_event.is_set():
|
|
||||||
log("测试已停止", level="error")
|
|
||||||
break
|
|
||||||
|
|
||||||
log(f"[{i}/{total}] 测试 {percentage}% 窗口...", level="info")
|
|
||||||
try:
|
|
||||||
image_path = _ensure_window_image(width, height, percentage)
|
|
||||||
except Exception as e:
|
|
||||||
log(f" 图像生成失败: {e}", level="error")
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.signal_service.send_image(image_path)
|
|
||||||
except Exception as exc:
|
|
||||||
log(f" {percentage}% 窗口发送失败: {exc},跳过", level="error")
|
|
||||||
continue
|
|
||||||
|
|
||||||
log(f"等待 {wait_time} 秒...", level="info")
|
|
||||||
time.sleep(wait_time)
|
|
||||||
|
|
||||||
try:
|
|
||||||
x, y, lv, _X, _Y, _Z = self.ca.readAllDisplay()
|
|
||||||
except Exception as e:
|
|
||||||
log(f" 采集亮度异常: {e}", level="error")
|
|
||||||
continue
|
|
||||||
if lv is None:
|
|
||||||
log(f" {percentage}% 窗口采集失败", level="error")
|
|
||||||
continue
|
|
||||||
|
|
||||||
log(f"采集亮度: {lv:.2f} cd/m²", level="info")
|
|
||||||
results.append((percentage, x, y, lv, _X, _Y, _Z))
|
|
||||||
|
|
||||||
log("=" * 60, level="separator")
|
|
||||||
log(f"Local Dimming 测试完成 ({len(results)}/{total})", level="success")
|
|
||||||
log("=" * 60, level="separator")
|
|
||||||
|
|
||||||
self.ld_test_results = results
|
|
||||||
self._dispatch_ui(self.update_ld_results, results)
|
|
||||||
self._dispatch_ui(self.ld_start_btn.config, state=tk.NORMAL)
|
|
||||||
self._dispatch_ui(self.ld_stop_btn.config, state=tk.DISABLED)
|
|
||||||
self._dispatch_ui(self.ld_save_btn.config, state=tk.NORMAL)
|
|
||||||
|
|
||||||
threading.Thread(target=worker, daemon=True).start()
|
|
||||||
|
|
||||||
|
|
||||||
def update_ld_results(self: "PQAutomationApp", results):
|
def update_ld_results(self: "PQAutomationApp", results):
|
||||||
"""把批量测试结果填入 Treeview。"""
|
"""把批量测试结果填入 Treeview。"""
|
||||||
for percentage, x, y, lv, _X, _Y, _Z in results:
|
for row in results:
|
||||||
self.ld_tree.insert(
|
self.ld_tree.insert(
|
||||||
"", tk.END,
|
"", tk.END,
|
||||||
values=(f"{percentage}%", f"{lv:.2f}", f"{x:.4f}", f"{y:.4f}"),
|
values=(
|
||||||
|
row["test_item"],
|
||||||
|
row["pattern"],
|
||||||
|
row["value"],
|
||||||
|
row["x"],
|
||||||
|
row["y"],
|
||||||
|
row["time"],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def stop_local_dimming_test(self: "PQAutomationApp"):
|
def stop_local_dimming_test(self: "PQAutomationApp"):
|
||||||
"""请求停止当前 Local Dimming 测试。"""
|
"""兼容旧接口,无操作。"""
|
||||||
ev = getattr(self, "ld_stop_event", None)
|
return
|
||||||
if ev:
|
|
||||||
ev.set()
|
|
||||||
|
|
||||||
|
|
||||||
def send_ld_window(self: "PQAutomationApp", percentage):
|
def send_ld_window(self: "PQAutomationApp", percentage):
|
||||||
@@ -192,7 +267,7 @@ def send_ld_window(self: "PQAutomationApp", percentage):
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.log_gui.log(f"🔆 发送 {percentage}% 窗口...", level="info")
|
self.log_gui.log(f"🔆 发送 {percentage}% 窗口...", level="info")
|
||||||
self.current_ld_percentage = percentage
|
_set_current_ld_pattern(self, "峰值亮度", f"{percentage}%窗口", percentage)
|
||||||
|
|
||||||
def send():
|
def send():
|
||||||
width, height = self.signal_service.current_resolution()
|
width, height = self.signal_service.current_resolution()
|
||||||
@@ -215,12 +290,120 @@ def send_ld_window(self: "PQAutomationApp", percentage):
|
|||||||
threading.Thread(target=send, daemon=True).start()
|
threading.Thread(target=send, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def send_ld_checkerboard(self: "PQAutomationApp", center_white):
|
||||||
|
"""发送棋盘格图案(手动模式)。"""
|
||||||
|
if not self.signal_service.is_connected:
|
||||||
|
messagebox.showwarning("警告", "请先连接 UCD323 设备")
|
||||||
|
return
|
||||||
|
|
||||||
|
pattern_label = "棋盘格(中心白)" if center_white else "棋盘格(中心黑)"
|
||||||
|
self.log_gui.log(f"🔲 发送 {pattern_label}...", level="info")
|
||||||
|
_set_current_ld_pattern(self, "棋盘格对比度", pattern_label)
|
||||||
|
|
||||||
|
def send():
|
||||||
|
width, height = self.signal_service.current_resolution()
|
||||||
|
try:
|
||||||
|
image_path = _ensure_checkerboard_image(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
DEFAULT_CHESSBOARD_GRID,
|
||||||
|
center_white,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self._dispatch_ui(self.log_gui.log, f"图像生成失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.signal_service.send_image(image_path)
|
||||||
|
ok = True
|
||||||
|
except Exception:
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
msg = f"{pattern_label} 已发送" if ok else f"{pattern_label} 发送失败"
|
||||||
|
self._dispatch_ui(self.log_gui.log, msg)
|
||||||
|
|
||||||
|
threading.Thread(target=send, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def send_ld_black_pattern(self: "PQAutomationApp"):
|
||||||
|
"""发送全黑图案(手动模式)。"""
|
||||||
|
if not self.signal_service.is_connected:
|
||||||
|
messagebox.showwarning("警告", "请先连接 UCD323 设备")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.log_gui.log("⚫ 发送全黑画面...", level="info")
|
||||||
|
_set_current_ld_pattern(self, "黑电平", "全黑画面")
|
||||||
|
|
||||||
|
def send():
|
||||||
|
width, height = self.signal_service.current_resolution()
|
||||||
|
try:
|
||||||
|
image_path = _ensure_solid_image(width, height, (0, 0, 0), "black")
|
||||||
|
except Exception as e:
|
||||||
|
self._dispatch_ui(self.log_gui.log, f"图像生成失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.signal_service.send_image(image_path)
|
||||||
|
ok = True
|
||||||
|
except Exception:
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
msg = "全黑画面已发送" if ok else "全黑画面发送失败"
|
||||||
|
self._dispatch_ui(self.log_gui.log, msg)
|
||||||
|
|
||||||
|
threading.Thread(target=send, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def send_ld_instant_peak(self: "PQAutomationApp"):
|
||||||
|
"""发送瞬时峰值亮度图案:先黑场,再切到 10% 窗口并保持。"""
|
||||||
|
if not self.signal_service.is_connected:
|
||||||
|
messagebox.showwarning("警告", "请先连接 UCD323 设备")
|
||||||
|
return
|
||||||
|
|
||||||
|
pattern_label = f"黑场后切 {INSTANT_PEAK_WINDOW_PERCENTAGE}%窗口"
|
||||||
|
self.log_gui.log(f"⚡ 发送瞬时峰值图案: {pattern_label}", level="info")
|
||||||
|
_set_current_ld_pattern(
|
||||||
|
self,
|
||||||
|
"瞬时峰值亮度",
|
||||||
|
pattern_label,
|
||||||
|
INSTANT_PEAK_WINDOW_PERCENTAGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
def send():
|
||||||
|
width, height = self.signal_service.current_resolution()
|
||||||
|
try:
|
||||||
|
black_image = _ensure_solid_image(width, height, (0, 0, 0), "black")
|
||||||
|
peak_image = _ensure_window_image(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
INSTANT_PEAK_WINDOW_PERCENTAGE,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
self._dispatch_ui(self.log_gui.log, f"图像生成失败: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.signal_service.send_image(black_image)
|
||||||
|
time.sleep(INSTANT_PEAK_CAPTURE_DELAY)
|
||||||
|
self.signal_service.send_image(peak_image)
|
||||||
|
ok = True
|
||||||
|
except Exception:
|
||||||
|
ok = False
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
f"瞬时峰值图案已发送,当前保持 {INSTANT_PEAK_WINDOW_PERCENTAGE}%窗口"
|
||||||
|
if ok else
|
||||||
|
"瞬时峰值图案发送失败"
|
||||||
|
)
|
||||||
|
self._dispatch_ui(self.log_gui.log, msg)
|
||||||
|
|
||||||
|
|
||||||
def measure_ld_luminance(self: "PQAutomationApp"):
|
def measure_ld_luminance(self: "PQAutomationApp"):
|
||||||
"""测量当前显示的亮度并追加一行到 Treeview。"""
|
"""测量当前显示的亮度并追加一行到 Treeview。"""
|
||||||
if not self.ca:
|
if not self.ca:
|
||||||
messagebox.showwarning("警告", "请先连接 CA410 色度计")
|
messagebox.showwarning("警告", "请先连接 CA410 色度计")
|
||||||
return
|
return
|
||||||
if self.current_ld_percentage is None:
|
if getattr(self, "current_ld_pattern_label", None) is None:
|
||||||
messagebox.showinfo("提示", "请先发送一个窗口图案")
|
messagebox.showinfo("提示", "请先发送一个窗口图案")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -243,8 +426,12 @@ def measure_ld_luminance(self: "PQAutomationApp"):
|
|||||||
self._dispatch_ui(
|
self._dispatch_ui(
|
||||||
self.ld_tree.insert, "", tk.END,
|
self.ld_tree.insert, "", tk.END,
|
||||||
values=(
|
values=(
|
||||||
f"{self.current_ld_percentage}%",
|
getattr(self, "current_ld_test_item", "手动采集"),
|
||||||
f"{lv:.2f}", f"{x:.4f}", f"{y:.4f}", timestamp,
|
self.current_ld_pattern_label,
|
||||||
|
f"{lv:.4f}",
|
||||||
|
f"{x:.4f}",
|
||||||
|
f"{y:.4f}",
|
||||||
|
timestamp,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
self._dispatch_ui(self.log_gui.log, f"采集完成: {lv:.2f} cd/m²")
|
self._dispatch_ui(self.log_gui.log, f"采集完成: {lv:.2f} cd/m²")
|
||||||
@@ -258,6 +445,8 @@ def clear_ld_records(self: "PQAutomationApp"):
|
|||||||
self.ld_tree.delete(item)
|
self.ld_tree.delete(item)
|
||||||
self.ld_result_label.config(text="亮度: -- cd/m² | x: -- | y: --")
|
self.ld_result_label.config(text="亮度: -- cd/m² | x: -- | y: --")
|
||||||
self.current_ld_percentage = None
|
self.current_ld_percentage = None
|
||||||
|
self.current_ld_test_item = None
|
||||||
|
self.current_ld_pattern_label = None
|
||||||
self.log_gui.log("测试记录已清空", level="info")
|
self.log_gui.log("测试记录已清空", level="info")
|
||||||
|
|
||||||
|
|
||||||
@@ -282,7 +471,7 @@ def save_local_dimming_results(self: "PQAutomationApp"):
|
|||||||
try:
|
try:
|
||||||
with open(save_path, "w", newline="", encoding="utf-8-sig") as f:
|
with open(save_path, "w", newline="", encoding="utf-8-sig") as f:
|
||||||
writer = csv.writer(f)
|
writer = csv.writer(f)
|
||||||
writer.writerow(["窗口百分比", "亮度 (cd/m²)", "x", "y", "时间"])
|
writer.writerow(["测试项目", "图案", "亮度/结果", "x", "y", "时间"])
|
||||||
for item in self.ld_tree.get_children():
|
for item in self.ld_tree.get_children():
|
||||||
writer.writerow(self.ld_tree.item(item, "values"))
|
writer.writerow(self.ld_tree.item(item, "values"))
|
||||||
self.log_gui.log(f"测试结果已保存: {save_path}", level="success")
|
self.log_gui.log(f"测试结果已保存: {save_path}", level="success")
|
||||||
@@ -300,6 +489,9 @@ class LocalDimmingMixin:
|
|||||||
update_ld_results = update_ld_results
|
update_ld_results = update_ld_results
|
||||||
stop_local_dimming_test = stop_local_dimming_test
|
stop_local_dimming_test = stop_local_dimming_test
|
||||||
send_ld_window = send_ld_window
|
send_ld_window = send_ld_window
|
||||||
|
send_ld_checkerboard = send_ld_checkerboard
|
||||||
|
send_ld_black_pattern = send_ld_black_pattern
|
||||||
|
send_ld_instant_peak = send_ld_instant_peak
|
||||||
measure_ld_luminance = measure_ld_luminance
|
measure_ld_luminance = measure_ld_luminance
|
||||||
clear_ld_records = clear_ld_records
|
clear_ld_records = clear_ld_records
|
||||||
save_local_dimming_results = save_local_dimming_results
|
save_local_dimming_results = save_local_dimming_results
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ def create_log_panel(self: "PQAutomationApp"):
|
|||||||
|
|
||||||
|
|
||||||
def create_local_dimming_panel(self: "PQAutomationApp"):
|
def create_local_dimming_panel(self: "PQAutomationApp"):
|
||||||
"""创建 Local Dimming 测试面板 - 手动控制版"""
|
"""创建 Local Dimming 测试面板。"""
|
||||||
self.local_dimming_frame = ttk.Frame(self.content_frame)
|
self.local_dimming_frame = ttk.Frame(self.content_frame)
|
||||||
|
|
||||||
# 主容器
|
# 主容器
|
||||||
@@ -88,6 +88,52 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
|
|||||||
width=12,
|
width=12,
|
||||||
).pack(side=tk.LEFT, padx=3)
|
).pack(side=tk.LEFT, padx=3)
|
||||||
|
|
||||||
|
# ==================== 3. 其他手动图案 ====================
|
||||||
|
pattern_frame = ttk.LabelFrame(main_container, text="🧩 其他测试图案", padding=10)
|
||||||
|
pattern_frame.pack(fill=tk.X, pady=(0, 10))
|
||||||
|
|
||||||
|
ttk.Label(
|
||||||
|
pattern_frame,
|
||||||
|
text="手动发送棋盘格、瞬时峰值、黑场图案,再点击采集当前亮度",
|
||||||
|
font=("", 9),
|
||||||
|
foreground="#28a745",
|
||||||
|
).pack(pady=(0, 8))
|
||||||
|
|
||||||
|
pattern_row = ttk.Frame(pattern_frame)
|
||||||
|
pattern_row.pack(fill=tk.X)
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
pattern_row,
|
||||||
|
text="棋盘格(中心白)",
|
||||||
|
command=lambda: self.send_ld_checkerboard(True),
|
||||||
|
bootstyle="secondary",
|
||||||
|
width=14,
|
||||||
|
).pack(side=tk.LEFT, padx=3)
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
pattern_row,
|
||||||
|
text="棋盘格(中心黑)",
|
||||||
|
command=lambda: self.send_ld_checkerboard(False),
|
||||||
|
bootstyle="secondary",
|
||||||
|
width=14,
|
||||||
|
).pack(side=tk.LEFT, padx=3)
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
pattern_row,
|
||||||
|
text="瞬时峰值",
|
||||||
|
command=self.send_ld_instant_peak,
|
||||||
|
bootstyle="warning",
|
||||||
|
width=12,
|
||||||
|
).pack(side=tk.LEFT, padx=3)
|
||||||
|
|
||||||
|
ttk.Button(
|
||||||
|
pattern_row,
|
||||||
|
text="全黑画面",
|
||||||
|
command=self.send_ld_black_pattern,
|
||||||
|
bootstyle="dark",
|
||||||
|
width=12,
|
||||||
|
).pack(side=tk.LEFT, padx=3)
|
||||||
|
|
||||||
# ==================== 4. CA410 采集按钮 ====================
|
# ==================== 4. CA410 采集按钮 ====================
|
||||||
measure_frame = ttk.LabelFrame(main_container, text="📊 CA410 测量", padding=10)
|
measure_frame = ttk.LabelFrame(main_container, text="📊 CA410 测量", padding=10)
|
||||||
measure_frame.pack(fill=tk.X, pady=(0, 10))
|
measure_frame.pack(fill=tk.X, pady=(0, 10))
|
||||||
@@ -118,15 +164,19 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
|
|||||||
result_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
|
result_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
|
||||||
|
|
||||||
# Treeview
|
# Treeview
|
||||||
columns = ("窗口百分比", "亮度 (cd/m²)", "x", "y", "时间")
|
columns = ("测试项目", "图案", "亮度/结果", "x", "y", "时间")
|
||||||
self.ld_tree = ttk.Treeview(
|
self.ld_tree = ttk.Treeview(
|
||||||
result_frame, columns=columns, show="headings", height=10
|
result_frame, columns=columns, show="headings", height=10
|
||||||
)
|
)
|
||||||
|
|
||||||
for col in columns:
|
for col in columns:
|
||||||
self.ld_tree.heading(col, text=col)
|
self.ld_tree.heading(col, text=col)
|
||||||
if col == "窗口百分比":
|
if col == "测试项目":
|
||||||
self.ld_tree.column(col, width=100, anchor=tk.CENTER)
|
self.ld_tree.column(col, width=120, anchor=tk.CENTER)
|
||||||
|
elif col == "图案":
|
||||||
|
self.ld_tree.column(col, width=140, anchor=tk.CENTER)
|
||||||
|
elif col == "亮度/结果":
|
||||||
|
self.ld_tree.column(col, width=110, anchor=tk.CENTER)
|
||||||
elif col == "时间":
|
elif col == "时间":
|
||||||
self.ld_tree.column(col, width=120, anchor=tk.CENTER)
|
self.ld_tree.column(col, width=120, anchor=tk.CENTER)
|
||||||
else:
|
else:
|
||||||
@@ -176,6 +226,8 @@ def create_local_dimming_panel(self: "PQAutomationApp"):
|
|||||||
|
|
||||||
# 初始化当前窗口百分比(用于记录)
|
# 初始化当前窗口百分比(用于记录)
|
||||||
self.current_ld_percentage = None
|
self.current_ld_percentage = None
|
||||||
|
self.current_ld_test_item = None
|
||||||
|
self.current_ld_pattern_label = None
|
||||||
|
|
||||||
|
|
||||||
def toggle_local_dimming_panel(self: "PQAutomationApp"):
|
def toggle_local_dimming_panel(self: "PQAutomationApp"):
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"current_test_type": "hdr_movie",
|
"current_test_type": "screen_module",
|
||||||
"test_types": {
|
"test_types": {
|
||||||
"screen_module": {
|
"screen_module": {
|
||||||
"name": "屏模组性能测试",
|
"name": "屏模组性能测试",
|
||||||
|
|||||||
Reference in New Issue
Block a user