采集卡bug修复
This commit is contained in:
150
preview.py
150
preview.py
@@ -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):
|
||||||
"""运行预览"""
|
"""运行预览"""
|
||||||
|
|||||||
Reference in New Issue
Block a user