1

I found this keyboard module in Python which is used to log keyboard events (from what I got, mainly) using keyboard.record(), which takes in a string as a parameter, indicating at which keypress the function should stop.

So my question is.. is there any way to make the function stop at any keypress? As far as I know the module has no special keyword which would indicate such a thing.

Like I tried doing this

keys_pressed = keyboard.record(until='any')

But that's causing an error.

  • If you want the logger to stop at any keypress I'm not sure why do you want it in the 1st place. Btw, the event types generated by the module are _key down_ and _key up_. Also, the question should contain the error as well. – CristiFati Aug 30 '17 at 17:52

3 Answers3

1

I don't see the point to using keyboard.record() if all you need it for is to stop at (and record) only the first keypress.

Instead, you could use keyboard.read_key() like this:

import keyboard
k = keyboard.read_key()  # in my python interpreter, this captures "enter up"
k = keyboard.read_key()  # so repeat the line if in the python interpreter
J-L
  • 1,786
  • 10
  • 13
1

After digging around in the source code, it looks like this is not possible.

def record(until='escape'):
    """
    Records all keyboard events from all keyboards until the user presses the
    given key combination. Then returns the list of events recorded, of type
    `keyboard.KeyboardEvent`. Pairs well with
    `play(events)`.

    Note: this is a blocking function.
    Note: for more details on the keyboard hook and events see `hook`.
    """
    recorded = []
    hook(recorded.append)
    wait(until)
    unhook(recorded.append)
    return recorded

The parameter until is passed into wait(). Thus, wait() must have code to handle an arbitrary key press, which it does not.

def wait(combination=None):
    """
    Blocks the program execution until the given key combination is pressed or,
    if given no parameters, blocks forever.
    """
    wait, unlock = _make_wait_and_unlock()
    if combination is not None:
        hotkey_handler = add_hotkey(combination, unlock)
    wait()
    remove_hotkey(hotkey_handler)

Ultimately, there is no source code built to handle something like keyboard.record(until='any'), so you'll have to find a workaround. Consider checking How do I make python to wait for a pressed key. However, if you need to record the arbitrary key you would have used to stop the recording, then use J-L's workaround:

import keyboard
k = keyboard.read_key()  # in my python interpreter, this captures "enter up"
k = keyboard.read_key()  # so repeat the line if in the python interpreter
Aor
  • 185
  • 11
  • Yeah, I should've snooped around the source code myself before asking. Anyway, `read_key()` seems to work just fine for what I'm trying to do, thanks for the answer anyway though. – string_loginUsername Aug 30 '17 at 18:44
0

You can make a function that sets a hook for all keys.

import keyboard

def record_until(any_key=False):
    recorded = []

    keyboard.hook(recorded.append) # need this to capture terminator

    wait, unlock = keyboard._make_wait_and_unlock()

    if any_key:
        hook = keyboard.hook(unlock)

    wait()

    try:
        keyboard.remove_hotkey(hook)
    except ValueError: pass

    return recorded


record_until(any_key=True)
Oluwafemi Sule
  • 36,144
  • 1
  • 56
  • 81