Checking for a keypress without stop the execution of the script (unix way).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!/usr/bin/python
import os, sys
import tty
from select import select
class NotTTYException(Exception): pass
class TerminalFile:
def __init__(self,infile):
if not infile.isatty():
raise NotTTYException()
self.file=infile
#prepare for getch
self.save_attr=tty.tcgetattr(self.file)
newattr=self.save_attr[:]
newattr[3] &= ~tty.ECHO & ~tty.ICANON
tty.tcsetattr(self.file, tty.TCSANOW, newattr)
def __del__(self):
#restoring stdin
import tty #required this import here
tty.tcsetattr(self.file, tty.TCSADRAIN, self.save_attr)
def getch(self):
if select([self.file],[],[],0)[0]:
c=self.file.read(1)
else:
c=''
return c
if __name__=="__main__":
s=TerminalFile(sys.stdin)
print "Press q to quit..."
i=0
while s.getch()!="q":
sys.stdout.write("%08d\r"%i)
i+=1
print "-- END --"
|
This script must be executed into a terminal (unix/linux). It uses the module 'select' to test stdin before to do the reading. All the code is encapsulated into a object in order to restore the terminal when the object gets delete (eg: at the gc loop). That code is based in the code due Andrew Kuchling. Thanks to the python-es list, in concrete to Marcos Sánchez Provencio for the idea.
Thanks Chema, This is really useful. You saved me probably a few hours of work, since I have no background in working with Terminals. I just copied your code into a py file and I'm using it in my code. Works great :)