如何在Flet程序中关闭cv2窗口?ESC按键无效问题求助
问题根源
- OpenCV按键捕获无效:你没有创建OpenCV窗口(
cv2.imshow()),cv2.waitKey()只能在OpenCV窗口获得焦点时捕获按键,但你是通过Flet的Image组件展示画面,这方法完全没用。 - UI线程被阻塞:摄像头读取的
while循环直接跑在Flet主线程里,加上cv2.waitKey(0)的无限等待,导致Flet整个UI卡死,根本没法响应任何用户操作。 - 退出逻辑不完整:就算捕获到ESC键,你只调用了
cv2.destroyAllWindows(),但没终止循环,摄像头还是会持续读取。
修复后的完整代码
import cv2 import base64 import time import threading import flet as ft cap = cv2.VideoCapture(0) is_running = True # 控制摄像头循环的标志 def main(page: ft.Page): page.title = "fletCam" image_box = ft.Image() page.add(image_box) def update_images(): global is_running while cap.isOpened() and is_running: ret, frame = cap.read() if ret: # 编码帧为base64格式 jpg_img = cv2.imencode('.jpg', frame) b64_string = base64.b64encode(jpg_img[1]).decode('utf-8') image_box.src_base64 = b64_string page.update() time.sleep(1/30) # 控制帧率为30帧/秒,平衡流畅度与资源占用 else: break # 退出循环后释放摄像头资源 cap.release() # 启动后台线程处理摄像头读取,避免阻塞Flet UI主线程 threading.Thread(target=update_images, daemon=True).start() # 监听键盘事件,处理ESC键退出逻辑 def on_keyboard(e: ft.KeyboardEvent): global is_running if e.key == "Escape": is_running = False page.window_close() # 关闭Flet应用窗口 page.on_keyboard_event = on_keyboard if __name__ == "__main__": ft.app(target=main)
关键修复点
- 改用Flet原生键盘监听:通过
page.on_keyboard_event直接捕获ESC键,用is_running标志终止摄像头循环,同时关闭应用窗口。 - 后台线程隔离摄像头操作:用
threading.Thread把摄像头读取逻辑放到后台,保证Flet UI主线程能正常响应所有用户操作。 - 清理无效代码:删除没用的
cv2.waitKey()和cv2.destroyAllWindows(),只保留必要的摄像头资源释放操作。 - 优化帧率控制:把过高的帧率(115帧/秒)调整为更合理的30帧/秒,既保证画面流畅,又避免浪费系统资源。
内容的提问来源于stack exchange,提问作者Jibin
相关产品推荐
相关产品推荐

