采集卡bug修复

This commit is contained in:
Ray
2025-10-29 14:36:45 +08:00
parent 0e16ec99c3
commit cd43334957

View File

@@ -68,60 +68,58 @@ class PreviewWindow:
# 存储图像对象 # 存储图像对象
self.photo_objects = {} self.photo_objects = {}
def update_frames(): def update_frames_once():
"""更新帧""" """在主线程中更新一帧使用after循环"""
while self.running: if not self.running:
try: return
canvas.delete("all") try:
canvas.delete("all")
# 计算每个预览窗口的位置和大小 # 计算每个预览窗口的位置和大小
window_width = root.winfo_width() if root.winfo_width() > 1 else 1000 window_width = root.winfo_width() if root.winfo_width() > 1 else 1000
window_height = root.winfo_height() if root.winfo_height() > 1 else 700 window_height = root.winfo_height() if root.winfo_height() > 1 else 700
cell_width = window_width // columns cell_width = window_width // columns
cell_height = window_height // rows cell_height = window_height // rows
frame_idx = 0 frame_idx = 0
for idx in self.caps.keys(): for idx in self.caps.keys():
if idx in self.frames: if idx in self.frames:
row = frame_idx // columns row = frame_idx // columns
col = frame_idx % columns col = frame_idx % columns
x = col * cell_width x = col * cell_width
y = row * cell_height y = row * cell_height
# 调整图像大小 # 调整图像大小
frame = self.frames[idx] frame = self.frames[idx]
h, w = frame.shape[:2] h, w = frame.shape[:2]
scale = min(cell_width / w, cell_height / h) * 0.9 scale = min(cell_width / w, cell_height / h) * 0.9
new_w = int(w * scale) new_w = int(w * scale)
new_h = int(h * scale) new_h = int(h * scale)
resized_frame = cv2.resize(frame, (new_w, new_h)) resized_frame = cv2.resize(frame, (new_w, new_h))
# 转换为PIL图像 # 转换为PIL图像
pil_image = Image.fromarray(resized_frame) pil_image = Image.fromarray(resized_frame)
photo = ImageTk.PhotoImage(image=pil_image) photo = ImageTk.PhotoImage(image=pil_image)
self.photo_objects[idx] = photo # 保持引用避免被GC
self.photo_objects[idx] = photo
# 绘制图像 # 绘制图像
center_x = x + cell_width // 2 center_x = x + cell_width // 2
center_y = y + cell_height // 2 center_y = y + cell_height // 2
canvas.create_image(center_x, center_y, image=photo, anchor='center') canvas.create_image(center_x, center_y, image=photo, anchor='center')
# 绘制标签 # 绘制标签
name = self.caps[idx]['name'] name = self.caps[idx]['name']
canvas.create_text(center_x, y + 20, text=name, fill='white', font=('Arial', 12, 'bold')) canvas.create_text(center_x, y + 20, text=name, fill='white', font=('Arial', 12, 'bold'))
frame_idx += 1 frame_idx += 1
except Exception as e:
canvas.update() print(f"更新帧错误: {e}")
tk._default_root.update_idletasks() # 约30fps
except Exception as e: root.after(33, update_frames_once)
print(f"更新帧错误: {e}")
import time
time.sleep(0.03) # 约30fps
def on_canvas_click(event): def on_canvas_click(event):
"""点击画布事件""" """点击画布事件"""
@@ -141,9 +139,8 @@ class PreviewWindow:
canvas.bind('<Button-1>', on_canvas_click) canvas.bind('<Button-1>', on_canvas_click)
# 启动更新线程 # 使用after在主线程中循环刷新
update_thread = threading.Thread(target=update_frames, daemon=True) root.after(33, update_frames_once)
update_thread.start()
def on_closing(): def on_closing():
"""关闭窗口""" """关闭窗口"""
@@ -160,7 +157,7 @@ class PreviewWindow:
if self.large_window is not None and self.large_window.winfo_exists(): if self.large_window is not None and self.large_window.winfo_exists():
self.large_window.destroy() self.large_window.destroy()
self.large_window = tk.Tk() self.large_window = tk.Toplevel()
self.large_window.title(f"放大视图 - {self.caps[idx]['name']}") self.large_window.title(f"放大视图 - {self.caps[idx]['name']}")
self.large_window.geometry("1280x720") self.large_window.geometry("1280x720")
@@ -169,46 +166,35 @@ class PreviewWindow:
photo_obj = {} photo_obj = {}
def update_large_frame(): def update_large_once():
"""更新大窗口帧""" if not self.running or not self.large_window.winfo_exists():
while self.running: return
try: try:
if idx in self.frames and self.large_window.winfo_exists(): if idx in self.frames:
canvas.delete("all") canvas.delete("all")
frame = self.frames[idx] frame = self.frames[idx]
h, w = frame.shape[:2] h, w = frame.shape[:2]
# 调整到窗口大小 # 调整到窗口大小
window_width = self.large_window.winfo_width() if self.large_window.winfo_width() > 1 else 1280 window_width = self.large_window.winfo_width() if self.large_window.winfo_width() > 1 else 1280
window_height = self.large_window.winfo_height() if self.large_window.winfo_height() > 1 else 720 window_height = self.large_window.winfo_height() if self.large_window.winfo_height() > 1 else 720
scale = min(window_width / w, window_height / h) scale = min(window_width / w, window_height / h)
new_w = int(w * scale) new_w = int(w * scale)
new_h = int(h * scale) new_h = int(h * scale)
resized_frame = cv2.resize(frame, (new_w, new_h)) resized_frame = cv2.resize(frame, (new_w, new_h))
pil_image = Image.fromarray(resized_frame) pil_image = Image.fromarray(resized_frame)
photo = ImageTk.PhotoImage(image=pil_image) photo = ImageTk.PhotoImage(image=pil_image)
photo_obj['img'] = photo photo_obj['img'] = photo
canvas.delete("all") canvas.create_image(window_width // 2, window_height // 2, image=photo, anchor='center')
canvas.create_image(window_width // 2, window_height // 2, image=photo, anchor='center') except Exception as e:
print(f"更新大窗口错误: {e}")
self.large_window.after(33, update_large_once)
self.large_window.update() self.large_window.after(33, update_large_once)
else:
break
except Exception as e:
print(f"更新大窗口错误: {e}")
break
import time
time.sleep(0.03)
update_thread = threading.Thread(target=update_large_frame, daemon=True)
update_thread.start()
self.large_window.mainloop()
def run(self): def run(self):
"""运行预览""" """运行预览"""