首页 > 解决方案 > 为什么循环不在单独的线程中停止?

问题描述

我正在尝试使用 tkinter 并使用 OpenCV 构建一个简单的视频应用程序。我正在使用线程从相机捕获视频帧,将它们转换为 PIL 图像并将它们设置为 Tkinter 标签中的图像。该应用程序运行良好,包括按钮,尽管当我尝试关闭 Tkinter 窗口时出现问题。我使用协议来执行此操作,并将全局变量设置enablecam为 false,这应该停止循环和摄像头,但相反,它只是关闭 Tkinter 窗口并且摄像机继续运行。我也尝试将变量记录到控制台,但是一旦关闭 Tkinter 窗口,程序就会停止将输出记录到控制台。我不确定为什么或如何发生这种情况,但我怀疑它可能与全局变量有关。我也试过root.quit()而不是root.destroy()但这只会使窗口崩溃。这是应用程序的代码 -

import tkinter as tk
import threading
import cv2
from PIL import Image, ImageTk
import time
from imutils.video import VideoStream

img = cv2.imread('img_avatar.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img2 = Image.fromarray(img)
enablecam = True
print(img2)

root = tk.Tk()

label = tk.Label(root, text="Video Camera Application")
label.grid(row=0, column=0)

img3 = ImageTk.PhotoImage(img2)

image = tk.Label(root, image=img3)
image.grid(row=1, column=0)


def capture_video():
    video = VideoStream().start()
    time.sleep(2)

    global img2, enablecam, image, img3, img

    while enablecam:
        frame = video.read()

        try:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            img2 = Image.fromarray(frame)

            img3 = ImageTk.PhotoImage(img2)
            image.configure(image=img3)
            image.image = img3
        except Exception as e:
            video.stop()
            break
    img2 = Image.fromarray(img)

    img3 = ImageTk.PhotoImage(img2)
    image.configure(image=img3)
    image.image = img3
    video.stop()


use_camera = threading.Thread(target=capture_video)
use_camera.start()


def handleCam():
    global use_camera, enablecam, img3, img2, image, img
    if enablecam:
        enablecam = False
        img2 = Image.fromarray(img)

        img3 = ImageTk.PhotoImage(img2)
        image.configure(image=img3)
        image.image = img3
    else:
        enablecam = True
        use_camera = threading.Thread(target=capture_video)
        use_camera.start()


cambtn = tk.Button(text='Enable Cam', command=handleCam)
cambtn.grid(row=2, column=0)


def on_closing():
    global enablecam, img3, img2, image, img, root

    if enablecam:
        enablecam = False
        img2 = Image.fromarray(img)

        img3 = ImageTk.PhotoImage(img2)
        image.configure(image=img3)
        image.image = img3

    root.destroy()


root.protocol("WM_DELETE_WINDOW", on_closing)

root.mainloop()

如果您能帮我解决这个问题,那就太好了,在此先感谢。

标签: pythonopencvtkinterpython-multithreading

解决方案


发生这种情况是因为 while 循环没有得到任何命令enablecam = False。保持循环,我认为它应该工作。


推荐阅读