python-3.x - 在两个不同的 Windows tkinter python 上显示摄像机
问题描述
我有一个包含两个不同功能窗口的 GUI python 应用程序,我试图在 tkinter 应用程序的第二个窗口中显示摄像机。但是,视频帧总是显示在第一个窗口上!!不知道是线程问题还是相机库的问题。我的代码有什么问题吗?提前致谢。
# add the necessairy librairy
import tkinter as tk
import threading
import time
import subprocess
from imutils.video import VideoStream
import time
import imutils
import cv2
import argparse
from PIL import Image
from PIL import ImageTk
class PhotoBoothApp:
def __init__(self,vs):
# store the video stream object and output path, then initialize
# the most recently read frame, thread for reading frames, and
# the thread stop event
self.vs = vs
self.frame = None
self.thread = None
self.stopEvent_2 = None
# initialize the root window and image panel
self.root = tk.Tk()
self.panel = None
self.user_input = tk.StringVar(self.root)
self.but_frame = tk.Frame(self.root)
w = 800 # width for the Tk root
h = 500 # height for the Tk root
# get screen width and height
ws = self.root.winfo_screenwidth() # width of the screen
hs = self.root.winfo_screenheight() # height of the screen
# calculate x and y coordinates for the Tk master window
x = (ws/3) - (w/3)
y = (hs/3) - (h/3)
# set the dimensions of the screen
# and where it is placed
self.root.geometry('%dx%d+%d+%d' % (w, h, x, y))
# when open the second window i want it to be on toplevel; it means when i click outside the frame it won't get hide
self.root.title("Test thread")
# create a button, that when pressed, will take the current
# frame and save it to file
btn = tk.Button(self.but_frame, bd = '5',text=" photo ")
self.but_frame.pack(side="left")
# start a thread that constantly pools the video sensor for
# the most recently read frame
self.stopEvent_2 = threading.Event()
self.thread = threading.Thread(target=self.videoLoop, args=())
self.thread.start()
# set a callback to handle when the window is closed
self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose)
def videoLoop(self):
# DISCLAIMER:
# I'm not a GUI developer, nor do I even pretend to be. This
# try/except statement is a pretty ugly hack to get around
# a RunTime error that Tkinter throws due to threading
try:
# keep looping over frames until we are instructed to stop
while not self.stopEvent_2.is_set():
# grab the frame from the video stream and resize it to
# have a maximum width of 300 pixels
self.frame = self.vs.read()
self.frame = imutils.resize(self.frame, width=300)
#cv2.imshow('video player', self.frame)
# OpenCV represents images in BGR order; however PIL
# represents images in RGB order, so we need to swap
# the channels, then convert to PIL and ImageTk format
image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
image = ImageTk.PhotoImage(image)
# if the panel is not None, we need to initialize it
if self.panel is None:
self.panel = tk.Label(image=image)
self.panel.image = image
self.panel.pack(side="left", padx=10, pady=10)
# otherwise, simply update the panel
else:
self.panel.configure(image=image)
self.panel.image = image
except RuntimeError :
print("[INFO] caught a RuntimeError_________________________________________")
def onClose(self):
# set the stop event, cleanup the camera, and allow the rest of
# the quit process to continue
print("[INFO] closing...")
self.stopEvent_2.set()
self.vs.stop()
self.root.quit()
# here's the main window
Mafenetre = tk.Tk()
#set main window title
Mafenetre.title("GUI")
Mafenetre['bg']='white' # couleur de fond
# get screen width and height
wf1= Mafenetre.winfo_screenwidth()
hf1= Mafenetre.winfo_screenheight()
A = str(wf1)
B = str(hf1)
# set the dimensions of the screen
# and where it is placed
w = 500 # width for the Tk root
h = 500 # height for the Tk root
# get screen width and height
ws = Mafenetre.winfo_screenwidth() # width of the screen
hs = Mafenetre.winfo_screenheight() # height of the screen
# calculate x and y coordinates for the Tk master window
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
# set the dimensions of the screen
# and where it is placed
Mafenetre.geometry('%dx%d+%d+%d' % (w, h, x, y))
# add test button to the main window
reglage = tk.Button(Mafenetre, bd = '5',text=" PARAM ", bg='#c42034', fg='white',font= "Helvetica", 12))
reglage.pack(side=tk.TOP, padx=6,pady=35)
camera = VideoStream(0).start()
pba = PhotoBoothApp(camera)
Mafenetre.mainloop()
解决方案
推荐阅读
- docker - 无法使用 IP 访问 docker 容器 Web 应用
- javascript - 来自 Safari 中 Axios 的网络错误,但不是 Chrome(Firefox 整个其他问题)
- python-3.x - 如果 Soup 在网站上找不到部分,如何给我发消息?每个不和谐或 idk
- sql - 过去 12 个月的数据总和,其中每个月有 2 行数据——Spark SQL
- python - 使用 pyinstaller 时找不到脚本
- c# - 如何在基于 Linux 的服务器上创建 Office 文档?
- wpf - 禁用 DataGrid 组标题的可折叠性
- javascript - 仅通过 WebAudio 节点播放视频标签音频
- android - Kotlin - 返回回调事件
- c# - DataGridView OnRowPostPaint 绘制