Search code examples
pythonloopspynput

Listen For 2 Different Keystrokes in One Method (Pynput)


essentially my program listens for keystrokes and if it sees the "up" arrow pushed it starts printing the word test using a while loop that relies on "flag" being true. I would like the program to stop when the down key is pressed but I am unable to make that happen. I don't get any errors, it just doesn't stop.

Here is the code:

from pynput.keyboard import Key, Listener

flag = False

def doit():
    while flag:
        print("test")


def released(key):
    global flag
    if key == Key.up:
        flag = True
        doit()
    elif key == Key.down:
        print("stopped")
        flag = False


with Listener(on_release=released) as listener:
    listener.join()

When I press the down arrow "stopped" doesn't get printed so it seems like the if statement isn't being used at all. How can I fix this?


Solution

  • You're trying to do two things at once:

    1. Listen for keyboard input
    2. Do whatever doit() is supposed to do.

    The following program starts doit() on a separate thread and thus allows the main-thread to continue listening for keystrokes.

    from pynput.keyboard import Key, Listener
    from threading import Thread
    import time
    
    flag = False
    thread = None
    
    def doit():
        while flag:
            print("test")
            time.sleep(0.5)
    
    def released(key):
        global flag, thread
        if key == Key.up:
            flag = True
            thread = Thread(target = doit)
            thread.start()
        elif key == Key.down:
            print("stopped")
            flag = False
            if thread.is_alive():
                thread.join()
    
    
    with Listener(on_release=released) as listener:
        listener.join()
    

    thread.start() does not block execution, as doit() would. Only when calling thread.join() will the main-thread block until the thread is done. Notice that this depends on the main-thread setting flag = False, and without that, the thread might continue infinitely, and the main-thread would thus wait forever when calling thread.join(). There are a number of these kinds of problems that arise when stepping into the world of multithreading.