如何找到我的 tkinter 死机的原因?

时间:2021-08-01 15:07:21

标签: python opencv tkinter

我正在尝试使用某些界面制作屏幕录制程序。 独立播放时录音效果很好, 但是一旦我放入一个函数并用作按钮命令, tkinter 死了。 没有错误消息,只有一个死窗口。 我怎么能弄明白呢? 代码是:

import pyautogui
import cv2
import numpy as np
import keyboard
import time
from tkinter import*
from tkinter import messagebox

def record_stop(): 
    keyboard.press_and_release('q')

def screenrec(): #recording program
    resolution = (1920,1080)
    codec = cv2.VideoWriter_fourcc(*'XVID')
    filename = '{}.avi'.format(time.strftime('_%Y%m%d_%H%M%S'))
    fps = 60.0
    out = cv2.VideoWriter(filename, codec, fps, resolution)
    messagebox.showinfo('info', 'Recording start.')

    while True:
        img = pyautogui.screenshot() 
        frame = np.array(img) 
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 

        out.write(frame)
    
       if cv2.waitKey(1) == ord('q'):
           messagebox.showinfo('info', 'Recording stopped.')
           break
    
    out.release()
    cv2.destroyAllWindows()


root = Tk()
root.resizable(False, False)
root.title('Record program')

btnframe = LabelFrame(root, text='Record')
btnframe.pack(fill='x', padx=5, pady=5)

btn_start = Button(btnframe, text='Start recording', width=10, command=screenrec)
btn_start.pack(side='left', padx=5, pady=5)

btn_stop = Button(btnframe, text='Stop recording', width=10, command=record_stop)
btn_stop.pack(side='right', pady=5, padx=5)

root.mainloop()

2 个答案:

答案 0 :(得分:1)

您的 while 循环阻塞了 tkinter 的循环。所以使用线程模块使用线程

这是一个例子:

import pyautogui
import cv2
import numpy as np
import keyboard
import time
from tkinter import *
from tkinter import messagebox
from threading import Thread

def record_stop(): 
    keyboard.press_and_release('q')

def screenrec(): #recording program
    resolution = (1920,1080)
    codec = cv2.VideoWriter_fourcc(*'XVID')
    filename = '{}.avi'.format(time.strftime('_%Y%m%d_%H%M%S'))
    fps = 60.0
    out = cv2.VideoWriter(filename, codec, fps, resolution)
    messagebox.showinfo('info', 'Recording start.')

    while record:
        img = pyautogui.screenshot() 
        frame = np.array(img) 
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 

        out.write(frame)
    
        if cv2.waitKey(1) == ord('q'):
           messagebox.showinfo('info', 'Recording stopped.')
           break
    
    out.release()
    cv2.destroyAllWindows()


def switchRec():
    global record
    record = not record
    
    if record:
        btn_start.config(text="Stop recording")
        thread = Thread(target=screenrec)
        thread.setDaemon(True)
        thread.start()
        
    else:
        btn_start.config(text="Start recording")


root = Tk()
root.resizable(False, False)
root.title('Record program')

record = False

btnframe = LabelFrame(root, text='Record')
btnframe.pack(fill='x', padx=5, pady=5)

btn_start = Button(btnframe, text='Start recording', width=10, command=switchRec)
btn_start.pack(side='left', padx=5, pady=5)


root.mainloop()

答案 1 :(得分:0)

While 循环与 mainloop 混淆。试试这个:

import multiprocessing
.....
def screenrec(): #recording program
    resolution = (1920,1080)
    codec = cv2.VideoWriter_fourcc(*'XVID')
    filename = '{}.avi'.format(time.strftime('_%Y%m%d_%H%M%S'))
    fps = 60.0
    out = cv2.VideoWriter(filename, codec, fps, resolution)
    messagebox.showinfo('info', 'Recording start.')

    while True:
        img = pyautogui.screenshot() 
        frame = np.array(img) 
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 

        out.write(frame)
    
       if cv2.waitKey(1) == ord('q'):
           messagebox.showinfo('info', 'Recording stopped.')
           proc.terminate()
           break
    
    out.release()
    cv2.destroyAllWindows()

def new_process():
    proc = multiprocessing.Process(target=screenrec)
    proc.start()
btn_start = Button(btnframe, text='Start recording', width=10, command=new_process)
btn_start.pack(side='left', padx=5, pady=5)