Reputation: 229
I'm using Terminal to run a python script with a series of print statements, separated by the time.sleep function.
If I'm printing various items over a period of 10 seconds, I would like to be able to prevent the user from inputting new commands into the command line during this time.
Is this possible in Terminal? Is there a work-around?
My goal here is to be able to provide the user with a lot of print statements, then have them answer a question only after the question is asked.
Because I don't want to overwhelm the user, I want to time delay the print statements so it appears more manageable (well, it's really for theatrical effect).
ie
for i in range(10):
print "Eating cheeseburger..."
time.sleep(1)
response = raw_input("What is your favorite color?")
if response == "blue":
blah blah blah etc.
Right now, the user can input a response before the question is asked, and while the cheeseburger is still being eaten. I want to prevent this.
Upvotes: 0
Views: 951
Reputation: 34300
The following is a version of Saurabh Shirodkar's answer written for the Windows console using ctypes.
import sys
import msvcrt
import ctypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
ENABLE_ECHO_INPUT = 0x0004
def _check_bool(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.GetConsoleMode.errcheck = _check_bool
kernel32.GetConsoleMode.argtypes = (ctypes.c_void_p,
ctypes.POINTER(ctypes.c_ulong))
kernel32.SetConsoleMode.errcheck = _check_bool
kernel32.SetConsoleMode.argtypes = (ctypes.c_void_p, ctypes.c_ulong)
kernel32.FlushConsoleInputBuffer.errcheck = _check_bool
kernel32.FlushConsoleInputBuffer.argtypes = (ctypes.c_void_p,)
def echo_input(enable=True, conin=sys.stdin):
h = msvcrt.get_osfhandle(conin.fileno())
mode = ctypes.c_ulong()
kernel32.GetConsoleMode(h, ctypes.byref(mode))
if enable:
mode.value |= ENABLE_ECHO_INPUT
else:
mode.value &= ~ENABLE_ECHO_INPUT
kernel32.SetConsoleMode(h, mode)
def flush_input(conin=sys.stdin):
h = msvcrt.get_osfhandle(conin.fileno())
kernel32.FlushConsoleInputBuffer(h)
if __name__ == '__main__':
import time
if sys.version_info[0] == 2:
input = raw_input
echo_input(False)
for i in range(10):
print(i)
time.sleep(1)
echo_input(True)
flush_input()
print(input("Answer now: "))
Upvotes: 1
Reputation: 334
The question is a platform specific one, as different operating systems handle standard input and output differently. I will attempt to answer your question for Linux:
You can use os.system
to access the linux command stty -echo
to make any text entered on the terminal invisible, and stty echo
to make it visible again.
The next thing you want to achieve is to clear the stdin buffer when user input is asked. This can be achieved through the termios
function tcflush
that can be used to flush all input that has been received but not read by the terminal yet.
import os
import time
import termios
import sys
os.system("stty -echo")
for i in range(10):
print(i)
time.sleep(1)
os.system("stty echo")
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
print(raw_input("Answer now:"))
Upvotes: 3