我有一個 tkinter 多幀應用程式,它在一頁中涉及多個頁面/框架或者當我導航到一個頁面時框架正在聚焦但它沒有關閉并且總是在后臺運行當我使用frame.quit()它關閉整個應用程式但我只想關閉那個相機
控制導航的主類
import tkinter as tk
import connectionPage
import startPage
// it has more than 15 pages but for example I have removed others
class tkinterApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
self.geometry(geometry)
self.attributes("-fullscreen", True)
StartPage=startPage.StartPage
ConnectionPage=connectionPage.connect_page
FrontCameraPage = frontCameraPage.FrontCameraPage
for F in (StartPage, ConnectionPage,FrontCameraPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(startPage.StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
if hasattr(frame, 'refresh'):
frame.refresh()
frame.tkraise()
def get_page(self, page_class):
return self.frames[page_class]
if __name__ == "__main__":
app = tkinterApp()
app.mainloop()
我的相機框架/頁面
class FrontCameraPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.label = tk.Label(self, text="FRONT CAMERA", font=MediumFont, bg="white").grid(row = 0,column = 0,columnspan=2, sticky = "nsew")
self.cameraFrame = tk.Frame(self, bg=gray)
self.cameraFrame.grid(row = 1,column = 0, sticky = "nsew")
self.buttonFrame = tk.Frame(self,bg = "white")
self.buttonFrame.grid(row = 1,column = 1, sticky = "nsew",padx = (10,0))
def end_trip():
self.cameraFrame.quit()# right now i am using quit but it is closing whole applicaiton i just want to close camera
self.Info = tk.Label(self.buttonFrame, text="FACE NOT\n DETECTED", font=MediumFont,bg = dark_red,fg ="white")
self.Info.grid(row=0, column=0, ipadx=8,pady = (0,5))
self.switchCamera = tk.Button(self.buttonFrame, text="SWITCH CAMERA", font=small_Font, bg=dark_blue, command=lambda: self.switch_camera(),fg ="white")
self.switchCamera.grid(row=1, column=0, ipadx=5,pady = (0,5))
self.endTrip = tk.Button(self.buttonFrame, text="END TRIP", font=small_Font, bg=dark_blue, command=pass = "White")
self.endTrip.grid(row=2, column=0, ipadx=10,pady = (0,5))
self.cancelButton = tk.Button(self.buttonFrame, text="Cancel", font=small_Font, bg=dark_blue, command=pass,fg="white")
self.cancelButton.grid(row=3, column=0, ipadx=10)
def refresh(self):
time.sleep(1)
width, height = 200, 200
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
lmain = tk.Label(self.cameraFrame)
lmain.pack()
def show_frame():
_, frame = cap.read()
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = PIL.Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_frame)
show_frame()
當我更改幀并轉到另一幀或單擊任何按鈕時,相機應該關閉。
uj5u.com熱心網友回復:
一種方法是使用虛擬事件來通知攝像機幀何時被切入或切出。
當相機幀接收到這些虛擬事件時,它可以根據事件的型別開始或停止捕獲。
以下是修改后的FrontCameraPage:
class FrontCameraPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.label = tk.Label(self, text="FRONT CAMERA", font=MediumFont, bg="white").grid(row = 0,column = 0,columnspan=2, sticky = "nsew")
self.cameraFrame = tk.Frame(self, bg=gray)
self.cameraFrame.grid(row = 1,column = 0, sticky = "nsew")
self.buttonFrame = tk.Frame(self,bg = "white")
self.buttonFrame.grid(row = 1,column = 1, sticky = "nsew",padx = (10,0))
self.Info = tk.Label(self.buttonFrame, text="FACE NOT\n DETECTED", font=MediumFont,bg = dark_red,fg ="white")
self.Info.grid(row=0, column=0, ipadx=8,pady = (0,5))
self.switchCamera = tk.Button(self.buttonFrame, text="SWITCH CAMERA", font=small_Font, bg=dark_blue, command=lambda: self.switch_camera(),fg ="white")
self.switchCamera.grid(row=1, column=0, ipadx=5,pady = (0,5))
self.endTrip = tk.Button(self.buttonFrame, text="END TRIP", font=small_Font, bg=dark_blue, fg = "White")
self.endTrip.grid(row=2, column=0, ipadx=10,pady = (0,5))
self.endTrip['command'] = self.stop_capture
self.cancelButton = tk.Button(self.buttonFrame, text="Cancel", font=small_Font, bg=dark_blue, fg="white")
self.cancelButton.grid(row=3, column=0, ipadx=10)
self.cancelButton['command'] = lambda: controller.show_frame(startPage.StartPage)
# setup callbacks for switching in and out events
self.bind('<<SwitchIn>>', self.start_capture)
self.bind('<<SwitchOut>>', self.stop_capture)
self.capture = None # task id for the capture loop
width, height = 200, 200
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# label for showing the captured image
self.lmain = tk.Label(self.cameraFrame)
self.lmain.pack()
def start_capture(self, event=None):
if self.capture is None:
# start the capture loop
self.show_frame()
print('capture started')
def stop_capture(self, event=None):
if self.capture:
# stop the capture loop
self.after_cancel(self.capture)
self.capture = None
print('capture stopped')
def show_frame(self):
ret, frame = self.cap.read()
if ret:
frame = cv2.flip(frame, 1)
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
self.imgtk = ImageTk.PhotoImage(image=img)
self.lmain.configure(image=self.imgtk)
self.capture = self.after(10, self.show_frame)
以下是修改后的tkinterApp:
class tkinterApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
...
self.frame = None # the current frame shown
self.show_frame(startPage.StartPage)
def show_frame(self, cont):
if self.frame:
# trigger the switching out handler of the frame
self.frame.event_generate('<<SwitchOut>>')
self.frame = self.frames[cont]
self.frame.tkraise()
# trigger the switching in handler of the frame
self.frame.event_generate('<<SwitchIn>>')
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/373629.html
