我可以获取键盘上按键被按下的时间吗

4 投票
5 回答
3136 浏览
提问于 2025-04-15 22:06

我正在做一个项目,目的是根据用户的打字风格来开发生物密码。假设一个用户输入密码20次,我们会记录下他的每次按键情况,比如:

按键保持时间:指的是某个按键被按下的时间。 双键时间:指的是按下一个不同按键所需的时间。

假设用户输入的密码是“COMPUTER”。我需要知道每个按键被按下的时间,类似于:

这个密码的按键保持时间是:

C-- 200毫秒 O-- 130毫秒 M-- 150毫秒 P-- 175毫秒 U-- 320毫秒 T-- 230毫秒 E-- 120毫秒 R-- 300毫秒

这样做的原因是,每个用户的按键保持时间都不同。比如,一个老年人在输入密码时,可能会比学生花更多的时间。而且这种时间是特定于每个人的。

为了完成这个项目,我需要记录每个按键被按下的时间。如果有人能指导我如何获取这些时间,我将非常感激。

从这里开始编辑……语言不是很重要,但我更倾向于用C语言。我更感兴趣的是获取数据集。

5 个回答

2

看看这个 ncurses,它是一个很棒的工具,可以帮助你获取终端中按键的信息。

你也可以看看这个 链接

6

记录按键按下(KeyDown)和松开(KeyUp)事件,然后对每个事件的时间戳进行比较。

http://code.activestate.com/recipes/203830/

补充说明:

你可能想看看 wxPython,这对你会有帮助:

http://www.wxpython.org/onlinedocs.php

特别是这里:

http://docs.wxwidgets.org/stable/wx_wxkeyevent.html#wxkeyevent

3

你提到你更喜欢用C语言,但既然你标记了Python... :)

另外,既然你说你想建立一个数据集,我猜你需要让用户输入一些随意的文本,所以你需要某种界面(可以是图形界面或其他形式)。

这里有个用pygame的简单例子。你可以很容易地修改它,让用户输入特定的单词,但现在这个例子只是让用户输入随意的文本,记录每次按键的时间,并在用户退出时(也就是按下Esc键时)打印出每次按住和双击的时间,按照用户输入的顺序显示。

正如Kibibu注意到的,实时显示用户正在输入的内容会引入延迟,这可能会影响真实的按键时间,所以这段代码只在用户按下“Enter”键时显示他输入的内容。

更新:现在它计算了双击和按住的时间(在这两种情况下都不包括Enter键)。

更新2:根据Adi的要求,改为显示每次按键的具体时间,而不是平均时间,按顺序显示。

import sys
from collections import defaultdict
from time import time
import pygame
from pygame.key import name as keyname
from pygame.locals import *

# Mapping of a key to a list of holdtimes (from which you can average, etc)
holdtimes = defaultdict(list)
# Mapping of a key pair to a list of digraph times
digraphs = defaultdict(list)
# Keys which have been pressed down, but not up yet.
pending = {}
# Last key to be de-pressed, corresponding time).
last_key = None
# Text that the user has typed so far (one sublist for every Enter pressed)
typed_text = [[]]

def show_times():
    all_text = [k for line in typed_text for k in line]
    print "Holdtimes:"
    for key in all_text:
        print "%s: %.5f" % (key, holdtimes[key].pop(0))

    print "Digraphs:"
    for key1, key2 in zip(all_text, all_text[1:]):
        print "(%s, %s): %.5f" % (key1, key2,
                                  digraphs[(key1, key2)].pop(0))

def time_keypresses(events):
    global last_key
    for event in events:
        if event.type == KEYDOWN:
            # ESC exits the program
            if event.key == K_ESCAPE:
                show_times()
                sys.exit(0)

            t = pending[event.key] = time()
            if last_key is not None:
                if event.key != K_RETURN:
                    digraphs[(last_key[0], keyname(event.key))].append(t - last_key[1])
                last_key = None
        elif event.type == KEYUP:
            if event.key == K_RETURN:
                update_screen()
                typed_text.append([])
                pending.pop(event.key)
                last_key = None
            else:
                t = time()
                holdtimes[keyname(event.key)].append(t - pending.pop(event.key))
                last_key = [keyname(event.key), t]
                typed_text[-1].append(keyname(event.key))
        # Any other event handling you might have would go here...

def update_screen():
    global screen
    screen.fill((255, 255, 255))

    header_font = pygame.font.Font(None, 42)
    header = header_font.render("Type away! Press 'Enter' to show.", True, (0, 0, 0))
    header_rect = header.get_rect()
    header_rect.centerx = screen.get_rect().centerx
    header_rect.centery = screen.get_rect().centery - 100

    text_font = pygame.font.Font(None, 32)
    user_text = text_font.render("".join(typed_text[-1]) if typed_text[-1] else "...",
                                 True, (0, 0, 255))
    text_rect = user_text.get_rect()
    text_rect.centerx = screen.get_rect().centerx
    text_rect.centery = screen.get_rect().centery    

    screen.blit(header, header_rect)
    screen.blit(user_text, text_rect)

    pygame.display.update()


if __name__ == '__main__':
    pygame.init()
    window = pygame.display.set_mode((800, 600))
    screen = pygame.display.get_surface()
    update_screen()
    while True:
        time_keypresses(pygame.event.get())

撰写回答