Skip to content
Advertisement

How to pause a pynput event listener

I am trying to make a program that will read the user’s inputs and if it detects a certain key combination, it will type a special character. Currently I am testing and I want the script to just output a ‘+’ after each character that the user types. I am using the pynput event listener to determine if a key was pressed and using a ‘Pause’ variable so that the output of the ‘+’ doesn’t cause the event listener to make an infinite loop. The problem is that the event listener is going into an infinite loop anyway and I am not sure why.

Current typed output after each key press: +++++++++++++++++++…

Desired typed output after each key press: +

Current console output after each key press:
pause is False
getting pressed
getting released
[‘f’]
paused
send outputs
unpaused
pause is False
getting pressed
getting released
[‘+’]
paused
send outputs
unpaused
pause is False
getting pressed
getting released
[‘+’]
paused
send outputs
unpaused
pause is False
getting pressed
getting released


Desired console output after each key press:
pause is False
getting pressed
getting released
[‘f’]
paused
send outputs
pause is True
unpaused

import pynput
import time
from pynput.keyboard import Key, Listener, Controller
keyboardOut = Controller()
PressedKeys = []
ReleasedKeys = []
Pause = False
def on_press(key):
    global PressedKeys, ReleasedKeys, Pause
    print("pause is "+str(Pause))
    if Pause == False:
        print("getting pressed")
        PressedKeys.append(key)
    else:
        return
    


def on_release(key):
    global PressedKeys, ReleasedKeys, Pause
    if Pause == False and len(PressedKeys) > 0:
        print("getting released")
        ReleasedKeys.append(key)
        test_frame()
    else:
        return

def test_frame():
    global Pause
    print(PressedKeys)
    Pause = True
    print("paused")
    print("send outputs")
    keyboardOut.press('+')
    keyboardOut.release('+')
    PressedKeys.clear()
    ReleasedKeys.clear()
    Pause = False
    print("unpaused")
    time.sleep(1)
    
# Collect events until released 
with Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join() 

How can I fix my code to *actually* pause the event listener. I am new to python, so I might just not understand how to update global variables correctly.

Advertisement

Answer

You have to stop the listener before using the keyboard controller. I hope this code helps out, I tried to get as close to what I thought you were looking for.

code:

from pynput import keyboard
from time import sleep

KeyboardOut = keyboard.Controller()
pressed_keys = []
released_keys = []

def on_press(key):
    try:
        pressed_keys.append(format(key.char))
    except AttributeError:
        print('special key {0} pressed'.format(
            key))

def on_release(key):
    if len(pressed_keys) > 0:
        released_keys.append(format(key))
        test_frame()
        return False
    if key == keyboard.Key.esc:
        # Stop listener
        return False

def test_frame():
    print('nn'+str(pressed_keys))
    print('paused')
    print('send outputs')
    KeyboardOut.press('+')
    KeyboardOut.release('+')
    pressed_keys.clear()
    released_keys.clear()
    with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
        listener.run()
    print('unpaused')
    sleep(1)
    return True

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.run()
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement