如何用Tkinter按钮关闭OpenCV窗口?按钮点击窗口冻结求助
问题描述
我尝试使用按钮关闭OpenCV窗口,使用键盘输入“q”时可正常销毁窗口,但点击按钮后,OpenCV窗口仅冻结且不再响应。
代码示例(Tkinter Button.py)
import threading, cv2 from tkinter import * from Colour_Detector import * root1 = Tk() root1.title('HSV Button') root1.iconbitmap("D:\Computer Science\Python\Cube\Cube.ico") root1.geometry('200x400') ##root2 = Tk() ##root2.title('Quit Button') ##root2.geometry('200x200') def colour_det(): colour_detector() def myClickHSV(): threading.Thread(target=colour_det).start() def quiting(): cv2.waitKey(1) cv2.destroyAllWindows() cv2.waitKey(1) def quitButton(): #threading.Thread(target=colour_det).stop() threading.Thread(target=quiting).start() # Disabled Button #myButton = Button(root, text='Click Me' state = DISABLED) #Button with padx as x width and pady as y width myButton1 = Button(root1, text='HSV', padx=85, pady=85, command=myClickHSV, fg='red', bg='yellow') myButton1.pack() myButton2 = Button(root1, text='Quit', padx=85, pady=85, command=quitButton) myButton2.pack() root1.update() root1.mainloop()
解决方案
问题根源在于当前实现的资源管理逻辑错误:
- 跨线程调用
cv2.destroyAllWindows()会和运行视频检测的主线程产生资源冲突,导致窗口冻结。 - 没有终止
colour_detector()中的视频循环,即使调用销毁窗口,后台的帧读取逻辑仍在运行,无法正常释放资源。
可以通过以下步骤修复:
- 给颜色检测函数添加控制标志
在Colour_Detector.py中加入全局标志位,用来终止视频循环:
# Colour_Detector.py import cv2 running = True def colour_detector(): global running # 假设你使用摄像头作为输入源 cap = cv2.VideoCapture(0) while running: ret, frame = cap.read() if not ret: break # 你的颜色检测处理逻辑 cv2.imshow("Colour Detector", frame) # 保留原有的键盘退出逻辑 if cv2.waitKey(1) & 0xFF == ord('q'): break # 循环结束后必须释放资源 cap.release() cv2.destroyAllWindows()
- 修改退出按钮的逻辑
不需要新开线程执行退出操作,直接修改标志位并触发OpenCV的事件检测:
# 主文件中 from Colour_Detector import running def quitButton(): global running running = False # 触发一次waitKey,让视频循环检测到标志位变化 cv2.waitKey(1)
- 移除冗余的线程调用
退出逻辑直接在Tkinter主线程执行即可,避免跨线程操作OpenCV资源,保证资源释放顺序正确。
修改后,点击按钮会停止视频循环,摄像头资源会被正确释放,OpenCV窗口也能正常关闭,不会再出现冻结情况。
内容的提问来源于stack exchange,提问作者Kiran K
相关产品推荐
相关产品推荐

