最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How can I interrupt a while loop at any point immediately with a custom hot key? - Stack Overflow

programmeradmin2浏览0评论

I have some code that records controller input in a while loop. This is working fine except for the start/stop function. I want to be able to stop the loop at any point with a single key press.

import inputs
import msvcrt
import keyboard

def record():
    '''
    Start and stop the input recording with the "\" key
    Records controller inputs when they are pressed and depressed and at what time.
    '''
    print('To start recording, press "q". Press it again to stop')
    if msvcrt.getwch() == 'q':
        print ("recording started...")
        while True:
            events = inputs.get_gamepad()
            for event in events:
                print(event.code)
record()

This is one of the things I've tried doing. I've also tried putting the recording function in a thread using the threading module. However, the same issue arises. It's that when I press 'q' it waits until I press another button on my controller. I want it to immediately stop the loop.

I've narrowed this down to the events = inputs.get_gamepad() line. It seems that it the loop waits here for a button to be pressed, then it can go back to the beginning causing the loop to correctly stop.

import inputs
import msvcrt
import keyboard

recording = True

def interrupt_record():
    global recording
    recording = False

def record():
    '''
    Start and stop the input recording with the "\" key
    Records controller inputs when they are pressed and depressed and at what time.
    '''
    print('To start recording, press "q". Press it again to stop')
    if msvcrt.getwch() == 'q':
        global recording
        recording = True
        print ("recording started...")

        while recording:
            events = inputs.get_gamepad()
            for event in events:
                print(event.code)

keyboard.add_hotkey('q', interrupt_record)
record()

I have some code that records controller input in a while loop. This is working fine except for the start/stop function. I want to be able to stop the loop at any point with a single key press.

import inputs
import msvcrt
import keyboard

def record():
    '''
    Start and stop the input recording with the "\" key
    Records controller inputs when they are pressed and depressed and at what time.
    '''
    print('To start recording, press "q". Press it again to stop')
    if msvcrt.getwch() == 'q':
        print ("recording started...")
        while True:
            events = inputs.get_gamepad()
            for event in events:
                print(event.code)
record()

This is one of the things I've tried doing. I've also tried putting the recording function in a thread using the threading module. However, the same issue arises. It's that when I press 'q' it waits until I press another button on my controller. I want it to immediately stop the loop.

I've narrowed this down to the events = inputs.get_gamepad() line. It seems that it the loop waits here for a button to be pressed, then it can go back to the beginning causing the loop to correctly stop.

import inputs
import msvcrt
import keyboard

recording = True

def interrupt_record():
    global recording
    recording = False

def record():
    '''
    Start and stop the input recording with the "\" key
    Records controller inputs when they are pressed and depressed and at what time.
    '''
    print('To start recording, press "q". Press it again to stop')
    if msvcrt.getwch() == 'q':
        global recording
        recording = True
        print ("recording started...")

        while recording:
            events = inputs.get_gamepad()
            for event in events:
                print(event.code)

keyboard.add_hotkey('q', interrupt_record)
record()
Share Improve this question asked Jan 19 at 21:24 RandomRepeaterRandomRepeater 112 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

The problem you are experiencing arises because inputs.get_gamepad() is blocking; that is, it waits for input events from the controller before returning, and prevents your loop from immediately responding to a key press.

Solution: Use Non-Blocking Input Detection For this, you could refactor your code to use a non-blocking method on the inputs.get_gamepad() function call so the loop could poll constantly for the stop condition rather than blocking indefinitely waiting on some controller input.

Here is one possible implementation:

import inputs
import keyboard

recording = True  # Control flag for the recording loop

def interrupt_record():
    """
    Interrupt the recording by setting the global recording flag to False.
    """
    global recording
    recording = False
    print("Recording stopped.")

def record():
    """
    Start and stop the input recording with the 'q' key.
    Records controller inputs when they are pressed and released, along with timestamps.
    """
    print('To start recording, press "q". Press it again to stop.')

    # Wait for the 'q' key to start recording
    while not keyboard.is_pressed('q'):
        pass

    global recording
    recording = True
    print("Recording started... Press 'q' again to stop.")

    # Main recording loop
    while recording:
        try:
            # Get gamepad events (non-blocking)
            events = inputs.get_gamepad()
            for event in events:
                print(event.code, event.state)
        except inputs.UnpluggedError:
            # Handle cases where the controller is not connected
            print("Controller disconnected.")
        except KeyboardInterrupt:
            # Allow for graceful exit with Ctrl+C
            break

# Add the hotkey for stopping the recording
keyboard.add_hotkey('q', interrupt_record)

# Start the recording function
record()

Maybe...

import inputs
import msvcrt
import keyboard

canRun = False

def stop():
    canRun = False

def record():
    '''
    Start and stop the input recording with the "\" key
    Records controller inputs when they are pressed and depressed and at what time.
    '''
    if msvcrt.getwch() == 'q':
        canRun = True
        print ("recording started...")
        while canRun:
            events = inputs.get_gamepad()
            for event in events:
                print(event.code)
record()
发布评论

评论列表(0)

  1. 暂无评论