I need to listen for certain keypresses in a python terminal program without pausing execution with raw_input
. I've seen people use a few windows specific ways of listening for keystrokes and I've seen people use large modules like tkinter and pygame which I want to avoid.
Is there a lightweight module out there that does this cross platform (at least ubuntu, windows, mac)? or is there a way to use just the event system from tkinter, pygame, etc...?
If not, how should I approach tackling this? My first thought is to redirect stdin to another process and keep checking to see if it contains one of my event keys.
Thank you @unutbu for taking the time to mark this question that is 3 years old and successfully answered as a duplicate of another question whose answers do not apply to this question because I specifically asked about a non-blocking solution.
I don't know of any cross-platform lightweight module that listens for keypresses. But here's a suggestion in case you want to implement something simple:
Check out this question on getting a single keypress at a time in the Python FAQ. You could experiment a bit with blocking reads from sys.stdin
and threading
. But this may only work on Unix. On Windows, you can use msvcrt.kbhit
.
Combining the keypress recipe from the Python FAQ and the msvcrt
module, the resulting kbhit
function would go like this:
try:
from msvcrt import kbhit
except ImportError:
import termios, fcntl, sys, os
def kbhit():
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
try:
while True:
try:
c = sys.stdin.read(1)
return True
except IOError:
return False
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)