как и почему не сбрасывается это приложение tkinter? - PullRequest
0 голосов
/ 10 апреля 2020

Я сделал это приложение, чтобы продолжать сохранять снимки при каждом нажатии кнопки моментального снимка, однако, когда я возвращаюсь на страницу приветствия, а затем на страницу камеры, я получаю эту ошибку:

cv2image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGBA) cv2.error: OpenCV(4.2.0) /io/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

Я исследовал всюду, но не мог найти способ сделать это. это ограничение в tkinter?

Я подозреваю, что ошибка может быть из-за того, что предыдущий снимок не очищен от cv2image, но я не знаю. Каков наилучший способ сброса приложения при вызове экрана приветствия?

import PIL
import tkinter as tk
from PIL import Image, ImageTk
import cv2
import time

class FR_GUI(tk.Tk):
    """this is the app
    it inherits from tk.Tk
    """

    def __init__(self):
        super().__init__()
        #self.title = "Self Registration Kiosk"
        self.geometry("700x1050")
        # self.attributes("-fullscreen", True)
        # self.wm_attributes("-topmost", 1)

        self.home = WelcomeScreen(self)
        self.home.pack(expand=True,fill=tk.BOTH)
        self.front = FrontPage(self)
        self.second = SecondPage(self)

    def welcome_screen(self):
        self.front.pack_forget()
        self.second.pack_forget()
        self.home.pack(expand=True,fill=tk.BOTH)

    def show_first(self):
        self.home.pack_forget()
        self.second.pack_forget()
        self.front.pack(expand=True, fill=tk.BOTH)
        self.front.show_frame()

    def show_second(self):
        self.front.cap.release()
        self.front.pack_forget()
        self.home.pack_forget()
        self.second.pack(expand=True, fill=tk.BOTH)


class WelcomeScreen (tk.Frame):
    def __init__(self, master):
        self.master = master
        super().__init__(self.master)
        #self.input = tk.StringVar()

        self.mainframe = tk.Frame(self)
        self.mainframe.pack(side=tk.TOP,padx=5,pady=80)#expand=True, fill=tk.BOTH)


        self.name_label = tk.Label(
            self.mainframe,
            text="Welcome to the self-registration portal ",
            font=("Courier", 18),
        )

        self.name_label.pack()

        self.ent_btn = tk.Button(
            self.mainframe,
            text="Enter",
            font=("Courier", 15),
            command=self.close_welcome)


        self.ent_btn.pack()

    def close_welcome(self):
        self.master.show_first()

class FrontPage(tk.Frame):
    """This is a class to make the front page
    it inherits from tk.Frame
    """


    def __init__(self, master):
        self.master = master
        super().__init__(self.master)


        self.mainframe = tk.Frame(self)
        self.mainframe.pack(side=tk.TOP,padx=5,pady=20,expand=True, fill=tk.BOTH)

        self.name_label = tk.Label(
            self.mainframe,
            text="Press Snapshot, picture will be taken in: ",
            font=("Courier", 13),
        )
        self.name_label.pack()

        self.label_count = tk.Label(
            self.mainframe,
            )
        self.label_count.pack()


        self.lmain = tk.Label(
            self.mainframe,
            anchor=tk.CENTER
            #text='cam frame'
        )
        self.lmain.pack()

        self.ent_btn = tk.Button(
            self.mainframe,
            text="Take Snapshot",
            font=("Courier", 15),
            command=self.onClick)#self.start_cam)


        self.ent_btn.pack(side = 'bottom')

        self.video_source = 0
        self.cap = cv2.VideoCapture(self.video_source)

        #get cam width & height
        self.width  = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)   # float
        self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

    def cam_release(self):
        self.cap.release()

    def show_frame(self):
        ret, frame = self.cap.read()
        frame = cv2.flip(frame, 1)
        cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
        img = PIL.Image.fromarray(cv2image)
        imgtk = ImageTk.PhotoImage(image=img)
        self.lmain.imgtk = imgtk
        self.lmain.configure(image=imgtk)
        self.lmain.after(10, self.show_frame)

    after_id = None

    def countdown(self,count):
        # change text in label
        self.label_count['text'] = count
        if count > 0:
            # call countdown again after 1000ms (1s)
            self.after(1000, self.countdown, count-1)
        else:
            self.snapshot()

    '''Start counting down.'''
    def onClick(self):
        self.countdown(2)

    def snapshot(self):
        # Get a frame from the video source
        ret, frame = self.cap.read()
        out_name = ("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg")
        cv2.imwrite(out_name, frame)
        self.cam_release()
        print(out_name)
        self.master.show_second()


class SecondPage(tk.Frame):
    """This is a class to make the second page
    it inherits from tk.Frame
    """

    def __init__(self, master):
        self.master = master
        super().__init__(self.master)


        self.firstName = tk.StringVar()
        self.lastName = tk.StringVar()
        #self.email = tk.StringVar()
        self.ph_one = tk.IntVar()



        self.mainframe = tk.Frame(self)
        self.mainframe.pack(fill=tk.BOTH, pady=80)

        self.label = tk.Label(
            self.mainframe, text="person not registered. \n please register: "
        )
        self.label.pack()

        self.top_frame = tk.Frame(self)
        self.top_frame.pack(side=tk.TOP,padx=5,pady=10)#expand=True, fill=tk.BOTH)

        self.center_frame = tk.Frame(self)
        self.center_frame.pack(side=tk.TOP,padx=5,pady=10)

        self.low_frame = tk.Frame(self)
        self.low_frame.pack(side=tk.TOP, padx=5,pady=10)#,expand = True)




        fname_label = tk.Label(self.top_frame,text="First Name",font=("Courier", 13))
        self.fname_entry = tk.Entry(self.top_frame, textvariable = self.firstName)

        lname_label = tk.Label(self.top_frame,text="Last Name ",font=("Courier", 13))
        self.lname_entry = tk.Entry(self.top_frame, textvariable = self.lastName)

        fname_label.grid(row=0, column=0)
        self.fname_entry.grid(row=0, column=1)

        lname_label.grid(row=1, column=0)
        self.lname_entry.grid(row=1, column=1)

        self.home_button = tk.Button(self.low_frame,text='Home',command=self.clear_widgets).grid(row=0,column=0,pady=4)
        self.submit_button = tk.Button(self.low_frame,text='Submit',command=self.form_submit).grid(row=0,column=1,pady=10)


    def form_submit(self):
        self.f_name = self.firstName.get()
        self.l_name = self.lastName.get()
        self.submit_label = tk.Label(self.center_frame,text="Thank you "+self.f_name+" "+self.l_name+" for your registeration",font=("Courier", 13))
        self.submit_label.grid(row=2,column=0)
        self.submit_label['text'] = ""



    def clear_widgets(self):
        self.refresh()
        self.master.welcome_screen()

    def refresh(self):
        self.fname_entry.delete(0,"end")
        self.lname_entry.delete(0,"end")
        self.fname_entry.focus_set()


app = FR_GUI()
#app.welcome_screen()
app.bind("<Escape>", exit)
app.mainloop()

Это рабочая демонстрация кода, проблема возникает при вызове главной страницы, когда я получаю сообщение об ошибке или иногда просто с предыдущий снимок застрял на экране фрейма.

как заставить приложение продолжать работать, не выходя из приложения и не снимая его?

...