首页 > 解决方案 > 持有 Pynput 忽略键

问题描述

我有一个程序,当用户第一次按下并按住一个键时打印经过的时间,并在释放键时再次打印。如果 5 秒后,用户在释放前按住键盘上的向上箭头 3 秒,程序应打印“0:05 response 1 ON”,然后打印“0:08 response 1 OFF”。我遇到的问题是按住键寄存器作为多次按键,导致每秒打印多次时间。任何想法如何将按下并按住的键视为单次按键?

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()

标签: pythonkeyboard-eventspynput

解决方案


该库本身不提供按键支持,但您可以轻松地利用计时器来模拟所述功能。

只需在开始时启动一个计时器来记录按下相关键的时间"RESPONSE 1"。如果新按键输入的时间与上次按键时间的差异超过阈值,则它(可能)是新按键,因此您写入文件“response 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()

推荐阅读