It may not be in great demand, but there are rare times when you want to get keystrokes while running in the background (that is, the Python app is out of focus). Java has a library called JNativeHook, which is reasonably easy to use, but I think that Java is used just for that. As a result of searching for a way to do it with Python, I got stuck, so I will leave a memorandum.
The first thing I looked up and found in various places was how to use PyHook. It seems that you can move in the background and take events such as key down and key up (Interesting miscellaneous feelings-moss about pyHook).
I dropped the corresponding version of pyHook from http://www.lfd.uci.edu/~gohlke/pythonlibs to give it a try.
wheel install pyHook‑1.5.1‑cp36‑cp36m‑win_amd64.whl
Installed with (it took a lot of time due to version problems etc.).
from pyHook import HookManager
from win32gui import PumpMessages, PostQuitMessage
class Keystroke_Watcher(object):
def __init__(self):
self.hm = HookManager()
self.hm.KeyDown = self.on_keyboard_event
self.hm.HookKeyboard()
def on_keyboard_event(self, event):
try:
print ('MessageName:',event.MessageName)
print ('Ascii:', repr(event.Ascii), repr(chr(event.Ascii)))
print ('Key:', repr(event.Key))
print ('KeyID:', repr(event.KeyID))
print ('ScanCode:', repr(event.ScanCode))
print ('Time:',event.Time)
print ('-'*5)
finally:
return True
def your_method(self):
pass
def shutdown(self):
PostQuitMessage(0)
self.hm.UnhookKeyboard()
watcher = Keystroke_Watcher()
PumpMessages()
I tried to execute, but it works fine when using Emacs, Sublime Text, but in a mysterious situation that it falls when I hit a key on the chrome browser. As an error
TypeError: KeyboardSwitch() missing 8 required positional arguments: 'msg', 'vk_code', 'scan_code', 'ascii', 'flags', 'time', 'hwnd', and 'win_name'
As a result of investigating, it seems to be a bug that occurs when executed on Python 3 system (https://stackoverflow.com/questions/26156633/pythoncom-crashes-on-keydown-when-used-hooked -to-certain-applications), I'm sorry.
PyHooked
When I was looking for a good alternative, I found something called pyHooked. Installation is
pip install pyhooked
And as you can see in example.py on the Github page,
from pyhooked import Hook, KeyboardEvent, MouseEvent
def handle_events(args):
if isinstance(args, KeyboardEvent):
print(args.key_code, args.current_key, args.event_type)
if isinstance(args, MouseEvent):
print(args.mouse_x, args.mouse_y)
hk = Hook() # make a new instance of PyHooked
hk.handler = handle_events # add a new shortcut ctrl+a, or triggered on mouseover of (300,400)
hk.hook() # hook into the events, and listen to the presses
By creating an event handler, you can easily take keyboard and mouse input in the background.
--Interesting miscellaneous feelings- What was moss about pyHook (http://d.hatena.ne.jp/favcastle/20120206/1328537612)
-
Recommended Posts