【发布时间】:2019-02-19 23:21:21
【问题描述】:
大家好,我有一个用于从网络摄像头读取视频的代码,并通过定时器线程将其显示到 tkinter 窗口中。 当用户单击显示按钮时,应用程序会创建一个线程并每隔 x 秒运行一次以逐帧显示。 这是问题所在:每几帧应用程序都会显示从视频源捕获的第一帧。 我知道这很奇怪,但我不知道为什么!!! 这是我的代码:
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")
【问题讨论】:
-
不确定这是否是根本原因,但我看到您从工作线程访问 GUI 元素——这是一个很大的危险信号。例如。 stackoverflow.com/questions/16745507/… 或 effbot.org/zone/tkinter-threads.htm