The pyHook library wraps the low-level mouse and keyboard hooks in the Windows Hooking API for use in Python applications. This short tutorial demonstrates how to set keyboard and mouse hooks, what information is available about events, and how to pass or block events.
Any application that wishes to receive notifications of global input events must have a Windows message pump. The easiest way to get one of these is to use the PumpMessages method in the Win32 Extensions package for Python.
import pythoncom
pythoncom.PumpMessages()
When run, this program just sits idle and waits for Windows events. If you are using a GUI toolkit (e.g. wxPython), this loop is unnecessary since the toolkit provides its own.
To receive mouse events, you must create a HookManager object and provide it will callbacks for the events in which you are interested. For instance, you can elect to receive only left button down events, only right button up events, only movement events, or all mouse events to name a few. Each event type can be directed to one and only one callback function.
import pythoncom, pyHook
def OnMouseEvent(event):
# called when mouse events are received
print 'MessageName:',event.MessageName
print 'Message:',event.Message
print 'Time:',event.Time
print 'Window:',event.Window
print 'WindowName:',event.WindowName
print 'Position:',event.Position
print 'Wheel:',event.Wheel
print 'Injected:',event.Injected
print '---'
# return True to pass the event to other handlers
return True
# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.MouseAll = OnMouseEvent
# set the hook
hm.HookMouse()
# wait forever
pythoncom.PumpMessages()
For a complete list of supported callbacks, see the properties of the HookManager class in the pyHook API documentation.
Keyboard hooks work in the same manner as mouse hooks, but return different information.
import pythoncom, pyHook
def OnKeyboardEvent(event):
print 'MessageName:',event.MessageName
print 'Message:',event.Message
print 'Time:',event.Time
print 'Window:',event.Window
print 'WindowName:',event.WindowName
print 'Ascii:', event.Ascii, chr(event.Ascii)
print 'Key:', event.Key
print 'KeyID:', event.KeyID
print 'ScanCode:', event.ScanCode
print 'Extended:', event.Extended
print 'Injected:', event.Injected
print 'Alt', event.Alt
print 'Transition', event.Transition
print '---'
# return True to pass the event to other handlers
return True
# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.KeyDown = OnKeyboardEvent
# set the hook
hm.HookKeyboard()
# wait forever
pythoncom.PumpMessages()
Callbacks for key and mouse events can decide whether or not to allow the event messages to pass to the windows for which they were intended. If a callback function returns True, the message is allowed to pass to callbacks registered by other applications and then onto its destination. If the function returns False, the message is blocked.
import pythoncom, pyHook
def OnKeyboardEvent(event):
# block only the letter A, lower and uppercase
return (event.Ascii not in (ord('a'), ord('A')))
# create a hook manager
hm = pyHook.HookManager()
# watch for all mouse events
hm.KeyDown = OnKeyboardEvent
# set the hook
hm.HookKeyboard()
# wait forever
pythoncom.PumpMessages()
Not all key and mouse events can be blocked. For instance, pyHook allows the Ctrl-Alt-Delete combo as is suggested by the Windows hooking documentation. (This behavior could be changed by hacking the pyHook C extension so it doesn't play as nicely.)
If a callback function does not return in a timely manner, the event is automatically forwarded along the hook callback chain, and, if no other callback blocks it, onto the destination window. Therefore, as little processing as possible should be done in a callback. Instead, the callback should add events to a queue for later processing by an application and quickly decide whether or not to block the message.
This tutorial introduces the basics of the pyHook library. Please refer to the full pyHook API documentation for more information.
The original author of this tutorial is Peter Parente, and the original location of it is here: http://mindtrove.info/articles/monitoring-global-input-with-pyhook/
It has been moved to the pyHook project space to consolidate all the documentation in one place.