event.key seems to not be Key [pynput]

Question:

I am writing an application which uses pynput to gather raw keyboard input. I needed a form of key event that could be instantiated, deleted, enabled, and disabled arbitrarily during runtime, so pynput’s Global Hotkey system wouldn’t work. So, I created my own event class:

keyEvents = []

class keyEvent():
    def __init__(self, key, callback, onPress, onRelease):
        self.key = key,
        self.callback = callback
        self.onPress = onPress
        self.onRelease = onRelease
        self.active = True
        self.calls = []
        keyEvents.append(self)

    # Called from listener thread, do not call callbacks from listener thread because then things happen at unpredictable times
    def fire(self, state):
        if self.active:
            print('{} fired {}({})'.format(self.key, self.callback, state))
            if self.onPress and state: self.calls.append(True)
            elif self.onRelease and not state: self.calls.append(False)

def _onKeyPress(key):
    print(key, key == keyboard.Key.enter)
    for event in keyEvents:
        if event.key == key: event.fire(True)
        else: print('Event did not fire {} != {}'.format(event.key, key))

def _onKeyRelease(key):
    for event in keyEvents:
        if event.key == key: event.fire(False)

And here I create several events, which are polled by menu.exec:

class menu():
    def __init__(self, name):
        self.name = name
        self.items = []
        self.keyEvents = [
            keyEvent(keyboard.Key.left,  self._keyLeft,  True, False),
            keyEvent(keyboard.Key.right, self._keyRight, True, False),
            keyEvent(keyboard.Key.up,    self._keyUp,    True, False),
            keyEvent(keyboard.Key.down,  self._keyDown,  True, False),
            keyEvent(keyboard.Key.enter, self._keyEnter, True, False)
        ]
        for event in self.keyEvents: event.active = False

    ...

    def exec(self):
        for event in self.keyEvents: event.active = True
        self.refresh()
        self.active = True
        while self.active:
            for event in self.keyEvents:
                for call in event.calls:
                    event.callback(call)
            time.sleep(0.1)

When I run the app, it gives me this output after I press the enter key:

Key.enter True
Event did not fire (<Key.left: <65361>>,) != Key.enter
Event did not fire (<Key.right: <65363>>,) != Key.enter
Event did not fire (<Key.up: <65362>>,) != Key.enter
Event did not fire (<Key.down: <65364>>,) != Key.enter
Event did not fire (<Key.enter: <65293>>,) != Key.enter

The first line tells me that the key passed to _onKeyPress is indeed keyboard.Key.enter. The last 5 lines tell me that _onKeyPress refused to call event.fire for all 5 events, including the one that was assigned to keyboard.Key.enter. Nowhere else in the code does event.key get modified. It is first set in keyEvent.__init__ and accessed in _onKeyPressed for the comparison and yet, the enter key that _onKeyPressed sees in the event object is different. Why is this?

Asked By: AwesomeCronk

||

Answers:

Solved! In keyEvent.__init__ I had this loose comma:

class keyEvent():
    def __init__(self, key, callback, onPress, onRelease):
        self.key = key,
        ...

Loose commas are like loose wires. They get in trouble.

Answered By: AwesomeCronk
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.