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
| registry = dict()
def fake_module(name, ns, keys=None):
'''helps to encapsulate state into something between module and class'''
keys = (name, ) if keys is None else tuple( [ name ] + list(keys))
m = registry.get(keys)
if m is None:
ns.update({ k: staticmethod(v) for k, v in ns.items() if callable(v) })
m = type(name, (object,), ns)
registry[keys] = m
return m
def helpers():
class Event:
def __init__(self):
self._callbacks = []
def register(self, cb):
if cb not in self._callbacks:
self._callbacks.append(cb)
def signal(self, *args, **kwds):
callbacks = self._callbacks[:]
for cb in callbacks:
try:
cb(*args, **kwds)
except Exception as e:
print (e)
self._callbacks.remove(cb)
return fake_module('helpers', locals())
def keystate():
h = helpers()
class KeyState(dict):
def __missing__(self, key):
dict.__setitem__(self, key, False)
def set(self, key, value):
dict.__setitem__(self, key, value)
key_state = KeyState()
key_release = h.Event()
key_press = h.Event()
def toggle(key):
state = key_state.get(key)
if state:
print ('key: %s is toggled On => Off' % key)
key_release.signal(key)
else:
print ('key: %s is toggled Off => On' % key)
key_press.signal(key)
key_state.set(key, not state)
return fake_module('keystate', locals())
if __name__ == '__main__':
import tkinter as tk
ks = keystate()
app = tk.Tk()
app.geometry("300x150")
app.event_add('<<ToggleKey>>', '<KeyPress>', '<KeyRelease>')
app.bind('<<ToggleKey>>', lambda e: ks.toggle(e.keysym))
text = tk.Text(app)
text.pack(fill='both', expand=True)
def insert_key(text, keysym):
text.insert('end', keysym)
ks.key_press.register(lambda key, text=text: insert_key(text, key))
tk.mainloop() |
Partager