-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkeyboard.py
122 lines (93 loc) · 3.65 KB
/
keyboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from typing import Any
from PyQt5.QtCore import QObject, pyqtSignal
from pynput.keyboard import HotKey, KeyCode, Listener, Key, Controller
from pynput._util.xorg import display_manager
keyboard = Controller()
ALPHA_LOWER = 'abcdefghijklmnopqrstuvwxyz'
ALPHA_UPPER = ALPHA_LOWER.upper()
class KeySequence(QObject):
_activate = pyqtSignal(name='activate')
_activated = pyqtSignal(name='activated')
def __init__(self, sequence, on_activate):
super(QObject, self).__init__()
self.sequence = sequence
self.on_activate = on_activate
self.activate.connect(self.do_activate)
def check(self, sequence):
if self.sequence == sequence:
self.activate.emit()
def do_activate(self):
self.on_activate()
self.activated.emit()
class QHotKey(HotKey, QObject):
_activate = pyqtSignal(name='activate')
def __init__(self, keys, on_activate):
self.on_activate = on_activate
QObject.__init__(self)
HotKey.__init__(self, keys, self.activate.emit)
self.activate.connect(self.do_activate)
def do_activate(self):
self.on_activate()
class DynamicHotKeyAndKeySequenceListener(Listener, QObject):
_key_sequence_activated = pyqtSignal(name='key_sequence_activated')
_pass_press = pyqtSignal(KeyCode, name='pass_press')
def __init__(self, *args, **kwargs):
Listener.__init__(self,
on_press=self.on_press,
on_release=self.on_release,
*args,
**kwargs)
QObject.__init__(self)
self.hotkeys = {}
self.key_sequences = []
self.current_sequence = ''
self.suppressed = False
def add_hotkey(self, key, hotkey):
self.hotkeys[key] = QHotKey(HotKey.parse(key), hotkey)
def add_key_sequence(self, key_sequence):
self.key_sequences.append(key_sequence)
key_sequence.activated.connect(self.clear_key_sequences)
key_sequence.activated.connect(self.key_sequence_activated)
if not self.suppressed:
with display_manager(keyboard._display) as dm:
self._suppress_start(dm)
self.suppressed = True
def clear_key_sequences(self):
key_sequences_copy = self.key_sequences.copy()
for key_sequence in key_sequences_copy:
self.remove_key_sequence(key_sequence)
self.current_sequence = ''
if self.suppressed:
with display_manager(keyboard._display) as dm:
self._suppress_stop(dm)
self.suppressed = False
def key_char(self, key):
char = None
try:
char = key.char.upper()
except AttributeError as error:
pass
except Exception as error:
pass
return char
def on_press(self, key):
for hotkey in self.hotkeys.values():
hotkey.press(self.canonical(key))
char = self.key_char(key)
if not char:
if key == Key.backspace:
self.current_sequence = self.current_sequence[0:-1]
return
if len(self.key_sequences) > 0:
self.current_sequence += char
# print('current_sequence: {}'.format(self.current_sequence))
for key_sequence in self.key_sequences:
key_sequence.check(self.current_sequence)
def on_release(self, key):
for hotkey in self.hotkeys.values():
hotkey.release(self.canonical(key))
def remove_hotkey(self, key):
self.hotkeys.pop(key, None)
def remove_key_sequence(self, key_sequence):
self.key_sequences.remove(key_sequence)
key_sequence.activate.disconnect()