首页 > 解决方案 > 从python中的另一个线程中停止一个线程

问题描述

我有一个函数可以重播 .json 文件中的一些步骤,以及另一个记录这些步骤的函数。一旦 playActions 函数同时完成(通过使用标志)并为每次迭代创建一个视频,我需要recordingScreen 函数停止,但它只为最后一个文件(迭代)创建视频

我尝试了一个标志,该标志在 playActions 函数完成时从 false 更改我还尝试了此示例链接中的队列并使用此示例链接中的线程安全。但是由于我是初学者,我无法在我的代码中正确实现它们中的任何一个,如下所示:threading.Event()

files= ["actions_test_10-07-2020_15-56-43.json", "actions_test_10-08-2020_14-59-00.json"]
date = datetime.today().strftime("%m-%d-%Y_%H-%M-%S")
Stop_recording = False

def main():
    initializePyAutoGUI()
    countdownTimer()
    for i in range(len(files)):
        global Stop_recording
        Stop_recording = False
        t1 = threading.Thread(target=playActions, args=[files[i]])
        t2 = threading.Thread(target=recordScreen)

        t1.start()
        t2.start()

        t1.join()
        t2.join()

    print("Done")


def recordScreen():
    output = '{}.avi'.format(date)
    img = pyautogui.screenshot()
    img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    # get info from img
    height, width, channels = img.shape
    # Define the codec and create VideoWriter object
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(output, fourcc, 20.0, (width, height))

    while not Stop_recording:
        img = pyautogui.screenshot()
        image = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
        out.write(image)
        StopIteration(0.5)

    out.release()
    cv2.destroyAllWindows()

def playActions(filename):
    # Read the file
    script_dir = os.path.dirname(__file__)
    filepath = os.path.join(script_dir, 'recordings', filename)
    with open(filepath, 'r') as jsonfile:
        # parse the json
        data = json.load(jsonfile)
        # loop over each action
        # Because we are not waiting any time before executing the first action, any delay before the initial
        # action is recorded will not be reflected in the playback.
        for index, action in enumerate(data):
            action_start_time = time()
            # look for escape input to exit
            if action['button'] == 'Key.esc':
                break
            # perform the action
            if action['type'] == 'keyDown':
                key = convertKey(action['button'])
                pyautogui.keyDown(key)
                print("keyDown on {}".format(key))
            elif action['type'] == 'keyUp':
                key = convertKey(action['button'])
                pyautogui.keyUp(key)
                print("keyUp on {}".format(key))
            elif action['type'] == 'click' and action['button'] == "Button.right":
                pyautogui.rightClick(action['pos'][0], action['pos'][1], duration=0.25)
                print("right click on {}".format(action['pos']))
            elif action['type'] == 'click' and action['button'] == "Button.left":
                # Check if the period between clicks is short and perform a double click then, otherwise
                # it performs a single click
                if index > 0:
                    if (data[index]['time']) - (data[index - 1]['time']) < 0.5:
                        pyautogui.doubleClick(action['pos'][0], action['pos'][1])
                        print("Double click on {}".format(action['pos']))
                pyautogui.leftClick(action['pos'][0], action['pos'][1], duration=0.25)
                print("left click on {}".format(action['pos']))

            # then sleep until next action should occur
            try:
                next_action = data[index + 1]
            except IndexError:
                # this was the last action in the list
                break
            elapsed_time = next_action['time'] - action['time']

            # if elapsed_time is negative, that means our actions are not ordered correctly. throw an error
            if elapsed_time < 0:
                raise Exception('Unexpected action ordering.')

            # adjust elapsed_time to account for our code taking time to run
            elapsed_time -= (time() - action_start_time)
            if elapsed_time < 0:
                elapsed_time = 0
            print('sleeping for {}'.format(elapsed_time))
            sleep(elapsed_time)
    global Stop_recording
    Stop_recording = True

标签: pythonmultithreadingopencvcv2

解决方案


推荐阅读