Search code examples
pythonloopswhile-loopkeyboardpynput

loop until key is pressed and repeat


Im trying to loop a print when a key is pressed and stop when another key is pressed.

Also I dont want to exit the program, it must continue listening for a key.

Problem: But what I get is a infinite loop because it cant listen to a another key while loop is True!

from pynput import keyboard
    
def on_press(key):
    if key == keyboard.Key.f9:
        while True:
            print("loading")
    if key == keyboard.Key.f10:
        # Stop listener
        return False

# Collect events until released
with keyboard.Listener(on_press=on_press) as listener:
    listener.join()

Im using pynput, docs here

EDIT

I did explained wrong one part, I wanted to do a loop when a certain key WAS pressed.


Solution

  • You can't run while True (or any long-running function) inside on_press
    because it blocks Listener. You have to run it in separated thread.

    You need on_press to create and start thread.
    And on_release to stop thread.
    It needs global variable. ie. running for this.

    I use datetime only to see if it displays new line or not.

    from pynput import keyboard
    import threading
    import datetime
    
    # --- functions ---
    
    def loading():
        while running:
             print("loading", datetime.datetime.now()) #, end='\r')
        
    def on_press(key):
        global running  # inform function to assign (`=`) to external/global `running` instead of creating local `running`
    
        if key == keyboard.Key.f9:
            running = True
            # create thread with function `loading`
            t = threading.Thread(target=loading)
            # start thread
            t.start()
            
        if key == keyboard.Key.f10:
            # stop listener
            return False
    
    def on_release(key):
        global running  # inform function to assign (`=`) to external/global `running` instead of creating local `running`
        
        if key == keyboard.Key.f9:
            # to stop loop in thread
            running = False
            
    #--- main ---
    
    with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()