Search code examples
pythonmultithreadingtkinterscreen-recording

How to implement my python code into tkinter gui code because nothing is working to stop the program because of multiple while loop runnning


I want to add this code into my tkinter gui code and i tried making it using command in buttons but the problem is, program wont stop running, it just freezes and i alrdy tried things like window.destroy(),exit() but it just closes the window but exit doesnt quits me out of program until i press the stop button myself

program code

import cv2
import numpy as np
from PIL import ImageGrab
screen_size = (1366, 768)
def recorder():
    fourcc = cv2.VideoWriter_fourcc(*"XVID")
    fps = 20.0
    output = cv2.VideoWriter("output.avi", fourcc, fps, (screen_size))
    while True:
        img = ImageGrab.grab()
        img_np = np.array(img)
        frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
        output.write(frame)
    output.release()
    cv2.destroyAllWindows()

Can someone help me add the both code and without freezing the window....I also tried threading but it didnt worked to stop the program.

tkinter gui code

from tkinter import *

window = Tk()
window.geometry("500x200+460+170")
window.resizable(0, 0)
window.configure(bg='#030818')

Label(window, text="Recording", fg="white",bg="#030818",font=("Helvetica", 23, "bold")).pack()
Button(window, text="Start Recording", bd=0, bg="gray",fg="white",font=("Helvetica", 15, "bold")).place(x=170,y=60)
Button(window, text="Stop Recording", bd=0, bg="gray",fg="white",font=("Helvetica", 15, "bold")).place(x=170,y=110)


window.mainloop()

Solution

  • First your code has never executed recorder() because you have not assigned any function to the two buttons.

    Second you need to run recorder() in a thread so that it won't block tkinter mainloop().

    In order to stop the recording, you need to find a way to break out from the while loop. Normally threading.Event object is used in multi-threaded application.

    Below are the required changes to achieve the goal:

    import threading
    ...
    
    recording = threading.Event()  # flag used for breaking out the while loop
    
    def recorder():
        print("recording started")
        fourcc = cv2.VideoWriter_fourcc(*"XVID")
        fps = 20.0
        output = cv2.VideoWriter("output.avi", fourcc, fps, screen_size)
        recording.set()  # set the recording flag
        while recording.is_set(): # keep running until recording flag is clear
            img = ImageGrab.grab().resize(screen_size)
            img_np = np.array(img)
            frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
            output.write(frame)
        output.release()
        cv2.destroyAllWindows()
        print("recording stopped")
    
    def start_recording():
        # make sure only one recording thread is running
        if not recording.is_set():
            # start the recording task in a thread
            threading.Thread(target=recorder).start()
    
    def stop_recording():
        # stop recording by clearing the flag
        recording.clear()
    
    ...
    Button(window, text="Start Recording", command=start_recording, bd=0, bg="gray",fg="white",font=("Helvetica", 15, "bold")).place(x=170,y=60)
    Button(window, text="Stop Recording", command=stop_recording, bd=0, bg="gray",fg="white",font=("Helvetica", 15, "bold")).place(x=170,y=110)
    ...