title: Real-time capture and processing of keypresses (e.g. keypress event)
body: <p><em>Note: I want to do this without using any external packages, like PyGame, etc.</em></p>
  
  <p>I am attempting to capture individual keypresses as they arrive and perform an action for specific characters, whether I simply want to "re-echo" the character, or not display it at all and do something else.</p>
  
  <p>I have found a cross-platform (though not sure about OS X) getch() implementation because I do not want to read a whole line like input() does:</p>
  
  <pre><code># http://code.activestate.com/recipes/134892/
  def getch():
      try:
          import termios
      except ImportError:
          # Non-POSIX. Return msvcrt's (Windows') getch.
          import msvcrt
          return msvcrt.getch
  
      # POSIX system. Create and return a getch that manipulates the tty.
      fd = sys.stdin.fileno()
      old_settings = termios.tcgetattr(fd)
      try:
          tty.setraw(fd)
          ch = sys.stdin.read(1)
      finally:
          termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
      return ch
  </code></pre>
  
  <p><strong>[Attempt 1]</strong> 
  I first tried a simple while-true loop to poll getch, but if I type too fast, characters go missing. Reducing the sleep time makes it worse. The debug statements only print on press of the enter key and not consistently in time nor position. (It appears there might be some line buffering going on?) Taking out the loop and sleep lets it work once but perfectly.</p>
  
  <pre><code>#!/usr/bin/env python3
  
  import sys
  import tty
  import time
  
  
  def main():
      while True:
          time.sleep(1)
          sys.stdout.write(" DEBUG:Before ")
          sys.stdout.write(getch())
          sys.stdout.write(" DEBUG:After ")
  
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p><strong>[Attempt 2]</strong> 
  I got an example for using a threaded approach (<a href="https://stackoverflow.com/a/14043979/2752206">https://stackoverflow.com/a/14043979/2752206</a>) but it "locks up" and won't accept any input (including <code>Ctrl-C</code>, and etc)..</p>
  
  <pre><code>#!/usr/bin/env python3
  
  import sys
  import tty
  import time
  import threading
  
  key = 'Z'
  
  
  def main():
      threading.Thread(target=getchThread).start()
  
      while True:
          time.sleep(1)
          sys.stdout.write(" DEBUG:Before ")
          sys.stdout.write(key)
          sys.stdout.write(" DEBUG:After ")
  
  
  def getchThread():
      global key
      lock = threading.Lock()
      while True:
          with lock:
              key = getch()
  
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>Does anyone have any advice or guidance? Or more importantly, can someone explain <em>why</em> the two attempts do not work? Thanks.</p>