123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #!/usr/bin/env python3
- import sys
- import termios
- import atexit
- from select import select
- class KBHit:
- def __init__(self) -> None:
- ''' Creates a KBHit object that you can call to do various keyboard things.
- '''
- self.stdin_fd = sys.stdin.fileno()
- self.set_kbhit_terminal()
- def set_kbhit_terminal(self) -> None:
- ''' Save old terminal settings for closure, remove ICANON & ECHO flags.
- '''
- # Save the terminal settings
- self.old_term = termios.tcgetattr(self.stdin_fd)
- self.new_term = self.old_term.copy()
- # New terminal setting unbuffered
- self.new_term[3] &= ~(termios.ICANON | termios.ECHO)
- termios.tcsetattr(self.stdin_fd, termios.TCSAFLUSH, self.new_term)
- # Support normal-terminal reset at exit
- atexit.register(self.set_normal_term)
- def set_normal_term(self) -> None:
- ''' Resets to normal terminal. On Windows this is a no-op.
- '''
- termios.tcsetattr(self.stdin_fd, termios.TCSAFLUSH, self.old_term)
- @staticmethod
- def getch() -> str:
- ''' Returns a keyboard character after kbhit() has been called.
- Should not be called in the same program as getarrow().
- '''
- return sys.stdin.read(1)
- @staticmethod
- def getarrow() -> int:
- ''' Returns an arrow-key code after kbhit() has been called. Codes are
- 0 : up
- 1 : right
- 2 : down
- 3 : left
- Should not be called in the same program as getch().
- '''
- c = sys.stdin.read(3)[2]
- vals = [65, 67, 66, 68]
- return vals.index(ord(c))
- @staticmethod
- def kbhit():
- ''' Returns True if keyboard character was hit, False otherwise.
- '''
- return select([sys.stdin], [], [], 0)[0] != []
- # Test
- if __name__ == "__main__":
- kb = KBHit()
- print('Hit any key, or ESC to exit')
- while True:
- if kb.kbhit():
- c = kb.getch()
- if c == '\x1b': # ESC
- break
- print(c)
- kb.set_normal_term()
|