4

I have a function that is called on_press. However, if the user constantly hits the key the keyboard event buffer queue gets really large and my function (which takes a few hundreds of ms) gets called even after the user has stopped pressing the key. How can I solve this issue?

from pynput import keyboard

def f1():
    print("starting f1()..")
    # f1 takes time to finish

def on_press(key):
    print("pressed some key")
    f1()

with keyboard.Listener(on_press=on_press) as listener:
    listener.join()
Varun Nayak
  • 290
  • 1
  • 7

3 Answers3

1

You could create a thread or process to achieve that,If you want to use thread, like this below:

from pynput import keyboard
import threading, time


def task():
    time.sleep(3)  # Simulate the time of cost
    print("task  finish")


def f1():
    print("starting task..")
    # f1 takes time to finish
    # create a thread to execute the task.
    threading.Thread(target=task).start()


def on_press(key):
    print("pressed some key")
    f1()


with keyboard.Listener(on_press=on_press) as listener:
    listener.join()

For sure, you could reduce the amount of functions,just for easy to understand, so I define 3 functions.

jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
  • Thanks, this got me to a working solution. I set a boolean before creating the thread and unset the boolean when the trhead was done. I used the boolean to make sure the thread would not be started a second time. – Hugo Oct 30 '21 at 08:22
1

An answer is given here: https://pythonadventures.wordpress.com/2019/11/16/flush-the-stdin/

The solution is to flush the buffer with:

import sys
import termios
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
xtof54
  • 1,233
  • 11
  • 15
1

You can create a queue to store the incoming keyboard keys and only add to it when it is empty like so:

from pynput import keyboard
from queue import Queue

queue = Queue()

def on_press(key):
    if queue.empty():
        queue.put(key)

listener = keyboard.Listener(on_press=on_press)
listener.start()

while True:
    key = queue.get()
    f1()