当我想停止时,线程不会停止

Thread doesn't stopping when i want to stop it

我有一个在 tkinter 中显示视频的程序 window。当我想关闭 window 时,我停止了视频线程。但它并没有停止。有四个函数:

    def start_video(self):
        if self.video is not None:
            self.video_thread_stopped = False
            try:
                if not self.video_thread.is_alive():
                    self.video_thread = threading.Thread(target=self.video_stream)
                    self.video_thread.start()
            except AttributeError:
                if self.video_thread is None:
                    self.video_thread = threading.Thread(target=self.video_stream)
                    self.video_thread.start()

start_video 函数启动视频线程

    def video_stream(self):
        _, frame = self.video.read()
        str_time = time.time()
        while frame is not None and getattr(self.video_thread, "running", True):
            self.current_frame += 1

            # resize and set image to label
            frame = cv2.resize(frame, self.video_frame_size)
            cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
            imgtk = ImageTk.PhotoImage(image=Image.fromarray(cv2image))
            self.video_label.config(image=imgtk)
            self.video_label.image = imgtk

            # waiting for frame rate
            while time.time() - str_time < (1 / self.fps):
                pass
            str_time = time.time()

            # reading next frame
            _, frame = self.video.read()
        print("exited from loop")

video_stream是线程函数

    def pause_video(self):
        if self.video_loaded:
            self.video_thread_stopped = True
            if self.video_thread is not None:

                # stop video
                self.video_thread.running = False
                print('before join')
                start_time = time.time()
                while self.video_thread.is_alive():
                    if time.time() - start_time > 1:
                        break
                print("after while")
                self.video_thread.join()
                print('after join')

pause_video 必须终止线程并停止流式传输视频

    def on_window_close(self):
        self.pause_video()
        print("thread stopped")
        self.root.destroy()

on_window_close 必须在关闭 tk 之前停止线程 window (我有以下代码)

root.protocol("WM_DELETE_WINDOW", w.on_window_close)

所以当我启动视频线程并按下 tk 上的关闭按钮时 window - 线程不会停止。这是一个终端输出

before join
after while

谁能帮我说说为什么它不能阻止 video_thread。谢谢!

我找到了解决方案。 在 start_video 方法中,您必须创建 video_thread 守护进程:

    def start_video(self):
        if self.video is not None:
            self.video_thread_stopped = False
            try:
                if not self.video_thread.is_alive():
                    self.video_thread = threading.Thread(target=self.video_stream)
                    self.video_thread.daemon = 1
                    # start audio
                    self.audio_class.start(self.current_frame, self.total_video_frames)
                    # start thread
                    self.video_thread.start()
            except AttributeError:
                if self.video_thread is None:
                    self.video_thread = threading.Thread(target=self.video_stream)
                    self.video_thread.daemon = 1
                    # start audio
                    self.audio_class.start(self.current_frame, self.total_video_frames)
                    # start thread
                    self.video_thread.start()

并且在 pause_video 方法中,您需要删除带有 video_thread.join()

的行
    def pause_video(self):
        if self.video_loaded:
            self.video_thread_stopped = True
            if self.video_thread is not None:
                # stop audio

                # stop video
                self.video_thread.running = False
                print("video stopped")
                self.audio_class.stop()
                print("audio stopped")
                # print('before join')
                start_time = time.time()
                while self.video_thread.is_alive():
                    # print("waiting for none")
                    if time.time() - start_time > 1:
                        # self.video_thread = None
                        break