0

I am trying to find a way to get KeyDown and KeyUp events in Python. With Pygame, this is easily done with pygame.KEYDOWN and pygame.KEYUP, but I am trying to find a way to do it without using a GUI.

Ideally, I would like to be able to define a function isKeyDown(key), which would return True if key is currently being held down, or return False if it isn't, but either way, it would move on with the code (it would be non-blocking). For example:

while True:
    if not isKeyDown("a"): #If 'a' isn't currently being pressed
         print ("You are not pressing 'a'")
    elif isKeyDown("a"): #If 'a' is being held down when this is run
         print ("You are pressing 'a'")
         print ("This is the end of this program")
         break

I've tried msvcrt.getch(), but that has two problems:

1) It stops the program until something is pressed, and

2) It doesn't really tell you if the key is being held down; it simply returns if the key is being pressed at the time. This can sometimes coincide since Windows repeats key presses when they are held down, but it is unlikely to happen when the while loop is being run at maximum speed.

I've also used msvcrt.kbhit(), but it sets itself to 1 if any key has been pressed and not read by msvcrt.getch(), and so that still runs into the problems of msvcrt.getch() and doesn't really return whether a key is actually currently being held down.

I am using Windows, so the curses module that many people have used to answer similar questions isn't available.

Is there a way to define such a isKeyDown() function in Windows without a GUI, preferably only using built-in modules? If this is not possible with the built-in Python modules, third-party modules would be okay, as long as they don't require a GUI.

Even using Pygame or Tkinter would be fine, as long as a way to turn off their GUIs.

If this is not possible, please tell me why, so I can stop looking for a solution (I have been trying to do little else for the past few days).

I am using Python 3.5.2 on a 64-bit Windows 10 laptop.

Sid
  • 11
  • 6
  • Please refer this question:http://stackoverflow.com/questions/13564851/generate-keyboard-events – Gaurav Dhama Aug 03 '16 at 21:53
  • 1
    @GaurabDhama: Completely unrelated. This question is asking, how to **receive** input. The question you linked to explains, how to **generate** input. – IInspectable Aug 03 '16 at 22:00
  • 1
    @GauravDhama I've looked at that question, and it explains ways of _generating_ keyboard events, whereas I'm looking for ways to get keyboard events as _inputs_. – Sid Aug 03 '16 at 22:02

1 Answers1

0

It looks like what you want to do is get pyhook. I believe it depends on the pywin32 library.

Basically what you want to do is look for creating a keylogger. That will give you non-blocking keyboard events. Of course you may want to use the win32 api to make sure that when the key is pressed it's your window that's in focus, if that matters to you.

I don't have my windows box accessible, or I'd be able to give you more code samples, but that should at least point you in the right direction.

Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • This took a while for me to implement, but it worked successfully. Thank You! By the way, if you know any Python command that can turn off (and later turn back on) the Windows key repeat mechanism, can you please tell me? – Sid Aug 04 '16 at 15:59
  • Excellent! I doubt you would be able to turn off repeat keys - I suspect that's a function of the keyboard (though I could totally be wrong there). Otherwise, I'd try digging through the google results for "Windows turn off repeat keys". I know you *could* do the accessibility thing, where you hold down left shift forever and then it takes about 3-5 seconds per letter that you type... not sure if that would do what you want, but it might! – Wayne Werner Aug 04 '16 at 16:07
  • 1
    Actually, I just found the pyHook module isn't even necessary; on Windows, the win32api and win32con modules are sufficient for this purpose: The win32api.GetAsyncKeyState() function satisfies the requirements. It works with pyHook too, but it's not required. – Sid Aug 05 '16 at 20:33
  • I thought it might be, but I wasn't sure and the only examples I found in my search used pyhook. Great to know, though! – Wayne Werner Aug 05 '16 at 20:37