Exemple #1
0
class KeyboardWatcher:
    def __init__(self, key_handlers: Sequence, verbose: bool = False):
        self._pool = KeyPool()
        self._verbose = verbose

        # sort them in order to give combinations precedence
        key_handlers = sorted(
            key_handlers,
            key=lambda x: len(x.trigger),
            reverse=True,
        )
        self._handlers = {handler.trigger: handler for handler in key_handlers}

        self._listener = None

        target = partial(infinite_handle_cycle,
                         active_keys=self.pressed,
                         handlers=self._handlers,
                         handle_method_name='press')
        hold_thread = Thread(target=target, daemon=True)
        hold_thread.start()

        self._listener = Listener(
            on_press=self.handle_press,
            on_release=self.handle_release,
            # suppress=True,
        )

    @property
    def pressed(self):
        return self._pool.pressed

    @property
    def released(self):
        return self._pool.released

    @staticmethod
    def _get_pressed_key(key: KeyCode):
        if isinstance(key, KeyCode):
            key_name = key.char
        elif isinstance(key, Key):
            key_name = key.name
        else:
            raise ValueError

        try:
            key_name = key_name.lower()
        except AttributeError:
            return None

        return key_name

    def handle_press(self, key: KeyCode):
        key_name = self._get_pressed_key(key)

        if (key_name and key_name not in self.pressed):
            self.pressed.add(key_name)

        if self._verbose:
            print(f'pressed: {self.pressed}')

    def handle_release(self, key: KeyCode):
        key_name = self._get_pressed_key(key)

        if key_name in self.pressed:
            self.pressed.remove(key_name)
            self.released.add(key_name)

            _handle_cycle(self.released, self._handlers, 'release')
            self.released.remove(key_name)

        if self._verbose:
            print(f'released: {self.pressed}')

    def join(self):
        while self._listener.is_alive():
            self._listener.join(0.1)

    def __enter__(self):
        self._listener.start()
        self._listener.wait()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._listener.stop()

    def start(self):
        self._listener.start()
        while True:
            time.sleep(0.1)
class KeyboardDriver():
    class Commands(Enum):
        Quit = 100
        Command1 = 1
        Command2 = 2
        Command3 = 3
        Command4 = 4
        Command5 = 5
        Command6 = 6
        Command7 = 7
        Command8 = 8
        Command9 = 9
        Command10 = 0
        Test = 101

        @classmethod
        def contains(cls, key):
            return any(key == item.value for item in cls)

        @classmethod
        def byvalue(cls, val):
            for item in cls:
                if item.value == val:
                    return item
            return None

    def __init__(self):
        # print('KeyboardDriver::__init__()')

        self._command = None

        # Setup the hook functions
        self.listener = Listener(on_press=self.__on_press__,
                                 on_release=self.__on_release__)

        self.listener.start()
        self.listener.wait()

    def get_command(self):
        rVal = self._command
        self._command = None
        return rVal

    def __on_press__(self, key):
        # For this case we can simply ignore the key down event
        try:
            ch = ord(key.char) - ord('0')

            if self.Commands.contains(ch):
                self._command = self.Commands.byvalue(ch)

        except AttributeError:
            pass

    def __on_release__(self, key):
        try:
            ch = key.char
            # print('U = {0}'.format(ch))

        except AttributeError:
            if key == Key.esc:
                self._command = self.Commands.Quit
Exemple #3
0
    if listen:
        #if hasattr(key, 'char') and key.char == '1': # there is no `Key.1` and `1`
        if str(key) == "'1'":  # it need `' '` in string
            label_var.set(label_var.get() + '1')
            print('1!')


# --- main ---

listen = False

root = tk.Tk()

label_var = tk.StringVar()

label = tk.Label(root, textvariable=label_var, width=10)
label.pack()

listener = Listener(on_press=onpress)
print('start')
listener.start()
try:
    listener.wait()
    print('mainloop')
    root.mainloop()
finally:
    print('stop')
    listener.stop()
    print('end')
    # without `listener.join()` because it runs as `daemon`
class Keyboard_Driver():
    class Keys(Enum):
        KEY1 = 'q'
        KEY2 = 'w'
        KEY3 = 'e'

        @classmethod
        def contains(cls, key):
            return any(key == item.value for item in cls)

        @classmethod
        def byvalue(cls, val):
            for item in cls:
                if item.value == val:
                    return item
            return None

    def __init__(self, on_press, on_release):
        # Check if we're on a Mac here, and see if we have GUID; if not throw an exception
        if sys.platform == 'darwin':
            # TODO : This really should exit entirely but for now make it print a message
            if os.getuid() != 0:
                # raise ZeroOneException("Must be run as root on a Mac, use 'sudo -s '")
                print(
                    "*** Should be run as root on a Mac, this may not work properly ***"
                )

        # Store the last_key_press
        self.keyEvents = {
            self.Keys.KEY1.value: None,
            self.Keys.KEY2.value: None,
            self.Keys.KEY3.value: None,
        }

        self.keyHandler = {
            self.Keys.KEY1.value: None,
            self.Keys.KEY2.value: None,
            self.Keys.KEY3.value: None,
        }

        # Setup the hook functions
        self.listener = Listener(on_press=self.__on_press__,
                                 on_release=self.__on_release__)

        self.listener.start()
        self.listener.wait()

        self.__client_on_press = on_press
        self.__client_on_release = on_release

    def __on_press__(self, key):
        try:
            ch = key.char

            if not self.Keys.contains(ch):
                self.__client_on_press(key)
            else:
                if self.keyEvents[ch] != ButtonEvent.BUTTON_DOWN:
                    self.keyEvents[ch] = ButtonEvent.BUTTON_DOWN
                    if self.keyHandler[ch] != None:
                        self.keyHandler[ch](self.Keys.byvalue(ch),
                                            ButtonEvent.BUTTON_DOWN)

            # print('Key = {0}'.format(ch))
        except AttributeError:
            self.__client_on_press(key)

    def __on_release__(self, key):
        try:
            ch = key.char

            if not self.Keys.contains(ch):
                self.__client_on_release(key)
            else:
                if self.keyEvents[ch] != ButtonEvent.BUTTON_UP:
                    self.keyEvents[ch] = ButtonEvent.BUTTON_UP
                    if self.keyHandler[ch] != None:
                        self.keyHandler[ch](self.Keys.byvalue(ch),
                                            ButtonEvent.BUTTON_UP)

        except AttributeError:
            self.__client_on_release(key)

    # Register a callback method to register for the events
    def register_key_event_handler(self, callback, key=Keys.KEY1):
        self.keyHandler[key.value] = callback