hello everyone i have a code for read video from webcam and show it into the tkinter window with timer threading. when user click show button, app make a thread and run it every x second to show frame by frame. here's the problem : every several frame app shows first frame that captured from video source. that's weird i know but i cant find out why!!! here's my code:
import tkinter as tk
from tkinter import ttk 
from tkinter import *
import threading
import cv2
import PIL.Image, PIL.ImageTk
from PIL import Image
from PIL import ImageTk
import time
class App(threading.Thread):
        def __init__(self, root, window_title, video_source=0):
            self.root = root
            self.root.title(window_title)
            self.video_source = video_source
            self.show_switch=False
            self.showButton = Button(self.root, text="PlayStream",command=self.showStram,width=15, padx="2", pady="3",compound=LEFT)
            self.showButton.pack()
            # Create a canvas that can fit the above video source size
            self.canvas = tk.Canvas(root, width = 530, height = 397, cursor="crosshair")
            self.canvas.pack()
            self.root.mainloop()
        def updateShow(self):
            # Get a frame from the video source
            cap=cv2.VideoCapture(0)
            while True:    
                if(cap.isOpened()):
                    #read the frame from cap
                    ret, frame = cap.read()
                    if ret:
                        #show frame in main window
                        self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
                        self.canvas.create_image(0, 0, image = self.photo, anchor = tk.NW)
                    else:
                        break
                        raise ValueError("Unable to open video source", video_source)
                    if self.show_switch==False:
                        cap.release()
                        return False
                time.sleep(0.0416666666666667)
            #release the cap
            cap.release()
        def showStram(self):
            if self.show_switch:
                self.showButton["text"]="StartStream"
                # self.showButton.configure(image=self.playIcon)
                self.show_switch=False
            else:
                self.showButton["text"]="StopStream"
                self.show_switch=True
                # self.showButton.configure(image=self.stopIcon)
                self.showTimer=threading.Thread(target=self.updateShow,args=())
                #self.showTimer.daemon=True
                self.showTimer.start()
App(tk.Tk(), "Main")
 
    