DISCLAIMER THIS GUIDE IS INTENDED FOR READERS RUNNING WINDOWS OS.
*Background: * By all accounts, I'm relatively new to programming. My first real
experience coding was taking a programming course one and a half years ago through my
college's cognitive science department that used python. Long story short is that I got
hooked, and have since learned to write in Matlab, AutoHotKey, Powershell, among other
languages.
A pet project that I've been working on involves monitoring the CapsLock on my computer so
that the behavior of the copy and paste functions change while its on. For example: if the
caps lock is active, and I copy a string to the clipboard, then the string will also be
added to a list in the python program.
While learning to do this, a number of hurdles got in the way, so I've decided to write
this post assembling what I've learned. I don't assume this guide to be definitive by any
means, but I wanted to get the information assembled together in case it helps anyone.
What Does This Guide Cover? This guide covers two options for monitoring user-input
from the keyboard and mouse using python. Which option is best for you will depend on your
particular needs and situation.
installer
Part 1: Using the msvcrt module's getch function The first module I will be covering is msvcrt. This module is included as part of the
standard library, and documentation can be found at the following links.
(https://docs.python.org/2/library/msvcrt.html) * http://effbot.org/librarybook/msvcrt.htm
The function I want to highlight in the module is the getch() function. When called, the
function will wait for you to enter a character and will return the character entered as a
string. (See the first link above for variants such as getwch() which does the same thing
but returns the unicode value)
Here is a short script to show how the function works (Note IDLE doesn't seem to like this
script. Saving it and clicking the file, or running the file from the command prompt should
work):
from msvcrt import getch
def getch_demo():
""" Demonstration of the getch function """
print 'Q to quit'
while True:
result = getch() # get character entered as string
print "You pressed {}".format(result) + '\r',
if result == 'Q' or result == 'q':
break
if __name__=='__main__':
getch_demo()
There are a few things in the functionality of getch that are worth noting.
we want to do something else while it's waiting for a key entry, a module such as
subprocess or threading might be needed. * (2) The console window must be the active window for it to register keypresses (You can
verify this by clicking outside the console window and entering a character). * (3) It doesn't monitor meta/modifier keys. It won't monitor keys such as the shift,
Ctrl, Window, Fn, etc. Also Arrow keys return capital leters such as "I",'S","M". * (4) The letter is maintained. So pressing Shift+S will return "S" instead of "s".
On the side-project I'm currently working on numbers (2) and (3) were deal-breakers for me:
as I'm trying to monitor the state of the caps-lock key, and I needed to be able to monitor
key presses without the console window being the active window. To do so lets look now at
using the win32api.
Part 2: Using the pywin32 library The second module I will be looking at is using the pywin32 library. There are quite a few
modules that are included in the library, but I'm going to be focusing on how to use some
of the functions from the win32api module to get the state of keys.
(WHAT THE LIBRARY IS)
win32api.GetKeyState(virtual_key_code) win32api.GetAsyncKeyState(virtual_key_code)
virtual_key_code will be an integer argument between 1-254. Which keycode coresponds to what key is typically somewhat opaque: the keycode for the *5
key* on the top row of the keyboard would be 0x3F which for our purposes is the same as
63.
However, you lucky reader, don't have to worry about the finer points of this conversion process. I've put together two dictionaries that will convert descriptions of the keys (e.g. 'F key' or 'CTRL key') to their virtual key codes, and vice-versa. Pastebin link