• 5
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

name Punditsdkoslkdosdkoskdo

How to do “hit any key” in python?

How would I do a "hit any key" (or grab a menu option) in Python?

  • raw_input requires you hit return.
  • Windows msvcrt has getch() and getche().

Is there a portable way to do this using the standard libs?

try:
    # Win32
    from msvcrt import getch
except ImportError:
    # UNIX
    def getch():
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        try:
            tty.setraw(fd)
            return sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
  • 34
Reply Report
try:
  os.system('pause')  #windows, doesn't require enter
except whatever_it_is:
  os.system('read -p "Press any key to continue"') #linux
  • 9
Reply Report
    • I just tested with Python 2.x and 3.x on Windows Vista, and it does not require Enter here. (Still does not handle something like indicating a menu choice via a single key press - but works at least on Vista for the "press any key to continue" case.)
      • 2
    • spawning a sub-process for io sync is just plain useless. do not do this, it will ruin non-interactive performance for no good reason.
      • 1
    • Also, TokenMacGuy, waiting for any key to be pressed IS interactive performance. And JohnMillikin, specialized tools ARE the Unix philosophy.

From the python docs:

import termios, fcntl, sys, os
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 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", `c`
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

This only works for Unix variants though. I don't think there is a cross-platform way.

  • 6
Reply Report
      • 1
    • The problem with this solution is that it consumes all available CPU cycles running the while loop. You can reduce this to almost nothing by inserting time.sleep(0.1) in the loop. If you insert this in place of "pass", then the loop will process strings of keystrokes as fast as possible, but when idle it will only check for characters 10 times a second.

A couple years ago I wrote a small library to do this in a cross-platform way (inspired directly by John Millikin's answer above). In addition to getch, it comes with a pause function that prints 'Press any key to continue . . .':

pause()

You can provide a custom message too:

pause('Hit any key')

If the next step is to exit, it also comes with a convenience function that calls sys.exit(status):

pause_exit(status=0, message='Hit any key')

Install with pip install py-getch, or check it out here.

  • 3
Reply Report

on linux platform, I use os.system to call /sbin/getkey command, e.g.

continue_ = os.system('/sbin/getkey -m "Please any key within %d seconds to continue..." -c  10')
if continue_:
   ...
else:
   ...

The benefit is it will show an countdown seconds to user, very interesting :)

  • 0
Reply Report

Trending Tags