From d3d12993230b0e577cb65200641297d1f3c15152 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2025 16:47:30 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E9=9B=86=E5=8D=A1bug=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- preview.py | 78 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/preview.py b/preview.py index e6cd3fd..58cf376 100644 --- a/preview.py +++ b/preview.py @@ -183,10 +183,9 @@ class PreviewWindow: if not self.running: return try: - canvas.delete("all") - # 如果没有加载任何采集卡,显示提示 if not self.caps: + canvas.delete("all") canvas.create_text( root.winfo_width() // 2, root.winfo_height() // 2, @@ -205,15 +204,21 @@ class PreviewWindow: cell_width = window_width // columns cell_height = window_height // rows + # 先收集所有需要显示的图像 + images_to_draw = [] + texts_to_draw = [] frame_idx = 0 + for idx in self.caps.keys(): + row = frame_idx // columns + col = frame_idx % columns + x = col * cell_width + y = row * cell_height + center_x = x + cell_width // 2 + center_y = y + cell_height // 2 + name = self.caps[idx]['name'] + if idx in self.frames and self.frames[idx] is not None: - row = frame_idx // columns - col = frame_idx % columns - - x = col * cell_width - y = row * cell_height - # 调整图像大小 try: frame = self.frames[idx] @@ -223,36 +228,42 @@ class PreviewWindow: new_h = int(h * scale) resized_frame = cv2.resize(frame, (new_w, new_h)) - + # 转换为PIL图像 pil_image = Image.fromarray(resized_frame) photo = ImageTk.PhotoImage(image=pil_image) # 保持引用,避免被GC self.photo_objects[idx] = photo - - # 绘制图像 - center_x = x + cell_width // 2 - center_y = y + cell_height // 2 - canvas.create_image(center_x, center_y, image=photo, anchor='center') - - # 绘制标签 - name = self.caps[idx]['name'] - canvas.create_text(center_x, y + 20, text=name, fill='white', font=('Arial', 12, 'bold')) - + + images_to_draw.append((photo, center_x, center_y)) + texts_to_draw.append((center_x, y + 20, name, 'white')) + frame_idx += 1 except Exception as e: - print(f"处理帧 {idx} 错误: {e}") + # 忽略pyimage相关错误,避免刷屏 + if "pyimage" not in str(e).lower(): + print(f"处理帧 {idx} 错误: {e}") + # 如果处理失败,显示等待提示 + texts_to_draw.append((center_x, center_y, f"{name}\n处理失败", 'red')) + frame_idx += 1 else: # 显示等待提示 - row = frame_idx // columns - col = frame_idx % columns - x = col * cell_width - y = row * cell_height - center_x = x + cell_width // 2 - center_y = y + cell_height // 2 - name = self.caps[idx]['name'] - canvas.create_text(center_x, center_y, text=f"{name}\n等待画面...", fill='gray', font=('Arial', 12)) + texts_to_draw.append((center_x, center_y, f"{name}\n等待画面...", 'gray')) frame_idx += 1 + + # 清空画布 + canvas.delete("all") + + # 绘制所有图像和文本 + for photo, x, y in images_to_draw: + canvas.create_image(x, y, image=photo, anchor='center') + + for x, y, text, color in texts_to_draw: + if color == 'white': + canvas.create_text(x, y, text=text, fill=color, font=('Arial', 12, 'bold')) + else: + canvas.create_text(x, y, text=text, fill=color, font=('Arial', 12)) + except Exception as e: print(f"更新帧错误: {e}") import traceback @@ -314,8 +325,7 @@ class PreviewWindow: window_height = self.large_window.winfo_height() if self.large_window.winfo_height() > 1 else 720 if idx in self.frames and self.frames[idx] is not None: - canvas.delete("all") - + # 先处理图像,再清空画布 frame = self.frames[idx] h, w = frame.shape[:2] @@ -327,8 +337,11 @@ class PreviewWindow: resized_frame = cv2.resize(frame, (new_w, new_h)) pil_image = Image.fromarray(resized_frame) photo = ImageTk.PhotoImage(image=pil_image) + # 保存引用到字典,确保不被GC photo_obj['img'] = photo + # 清空并绘制新图像 + canvas.delete("all") canvas.create_image(window_width // 2, window_height // 2, image=photo, anchor='center') else: # 显示等待提示 @@ -341,9 +354,8 @@ class PreviewWindow: font=('Arial', 16) ) except Exception as e: - print(f"更新大窗口错误: {e}") - import traceback - traceback.print_exc() + if "pyimage" not in str(e).lower(): # 忽略pyimage错误,避免刷屏 + print(f"更新大窗口错误: {e}") self.large_window.after(33, update_large_once) self.large_window.after(33, update_large_once)