Pynput игнорирует удерживаемую клавишу

У меня есть программа, которая печатает прошедшее время, когда пользователь впервые нажимает и удерживает клавишу, и снова печатает, когда клавиша отпущена. Если через 5 секунд пользователь нажимает и удерживает стрелку вверх на своей клавиатуре в течение 3 секунд, прежде чем отпустить, программа должна напечатать ответ 1 ON 0:05, а затем ответ 1 OFF 0:08. Проблема, с которой я сталкиваюсь, заключается в том, что удерживание клавиши регистрируется как несколько нажатий клавиш, в результате чего время печатается несколько раз в секунду. Любые идеи, как обрабатывать нажатие и удерживание клавиши как нажатие одной клавиши?

import time
from pynput import keyboard
from pynput.keyboard import Key, Listener

f = open("quick_data.txt", "a")
f.write(time.ctime() + "\n")

def show(key):
    if key == keyboard.Key.enter:
        global start
        start = time.perf_counter()
    if key == keyboard.Key.delete:
        return False
    if key == keyboard.Key.up:
        elapsed = time.perf_counter()
        x = time.gmtime(elapsed - start)
        y = time.strftime('%M:%S', x)
        f.write(str(y) + " response 1 ON" + "\n")

def on_release(key):
    if key == keyboard.Key.up:
        elapsed = time.perf_counter()
        x = time.gmtime(elapsed - start)
        y = time.strftime('%M:%S', x)
        f.write(str(y) + " response 1 OFF" + "\n")

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

person Alex Elfont    schedule 22.05.2021    source источник


Ответы (1)


Библиотека изначально не обеспечивает поддержку удержания нажатия клавиш, но вы можете легко использовать таймер для эмуляции указанной функциональности.

Просто запустите таймер в начале, чтобы зарегистрировать время нажатия клавиши, связанной с "RESPONSE 1". Если время ввода новой клавиши отличается от времени последнего нажатия клавиши более чем на пороговое значение, то это (вероятно) новое нажатие клавиши, и, следовательно, вы записываете в файл ответ 1 ON. Затем вы сбрасываете время последнего обнаруженного нажатия клавиши RESPONSE 1, чтобы убедиться, что алгоритм нажатия клавиши синхронизирован. Когда вы отпускаете клавишу, on_release запускает и завершает пару. Конечно, вы можете настроить и увеличить порог в соответствии с вашими конкретными потребностями.

from pynput import keyboard
from pynput.keyboard import Key, Listener

f = open("quick_data.txt", "a")
f.write(time.ctime() + "\n")
pushdown_up = time.perf_counter() # initialize variable to store the time when the key associated with RESPONSE 1 was pressed
def show(key):
    threshold = 0.10 # threshold for input timing to differentiate between a key being held and a new key
    if key == keyboard.Key.enter:
        global start
        start = time.perf_counter()
        print(start)
    if key == keyboard.Key.delete:
        return False
    if key == keyboard.Key.up:
        elapsed = time.perf_counter() 
        global pushdown_up # time of last detected keypress
        if elapsed - pushdown_up < threshold:
            # if another INPUT 1 press is detected again within a short threshold, then it is probably part of the current input press
            pass
        else: # else, then it is a start of a new input.
            x = time.gmtime(elapsed - start)
            y = time.strftime('%M:%S', x)
            f.write(str(y) + " response 1 ON" + "\n")
            print(str(y) + " response 1 ON" + "\n")
        pushdown_up = elapsed # set the last registered keypress's time\

def on_release(key):
    if key == keyboard.Key.up:
        elapsed = time.perf_counter()
        x = time.gmtime(elapsed - start)
        y = time.strftime('%M:%S', x)
        f.write(str(y) + " response 1 OFF" + "\n")
        print(str(y) + " response 1 OFF" + "\n")

with keyboard.Listener(
        on_press=show,
        on_release=on_release) as listener:
    listener.join()
person CommuteAndAssociate    schedule 23.05.2021