Reputation: 43
I have the following code to get user input to do certain tasks. What I want is to break out of the user prompt when some other task, outside this module, is completed. So even though the shell is showing 'Enter Command:', I want it to stop waiting for a prompt from the user and continue to the other task. Is this even possible and if so, how? Thanks in advance.
def get_user_input():
while True:
info = str(raw_input('Enter Command:'))
if info == 'exit':
break
if info == 'do_something':
do_something()
Edit: Actually this is already in a thread and the thread closes correctly. The issue is the screen is stuck on the user prompt even though the user prompt is useless at that point since the thread calling for the input is already closed. Any suggestions?
Upvotes: 2
Views: 2815
Reputation: 3360
I think you can use this answer to read until a timeout, then check a variable and exit if the variable is set to false. If not then attempt to read again.
https://stackoverflow.com/a/2904057/2066459
import sys, select
print "Answer me!"
while var:
i, o, e = select.select( [sys.stdin], [], [], 10 )
if (i):
print "You said", sys.stdin.readline().strip()
break
Upvotes: 0
Reputation: 3744
you can use signal module (linux / unix only)
import signal
class UserInputTimeoutError(Exception):
pass
def handler(signum, frame):
raise UserInputTimeoutError('no input from user')
# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
# This may hang indefinitely
user_input = raw_input('please insert something here:')
print('got %s from user' % user_input)
# cancel the alarm signal
signal.alarm(0)
except UserInputTimeoutError:
print('\nno input from user')
output when input is 'hello':
please insert something here:hello
got hello from user
output when no input for 5 seconds:
please insert something here:
no input from user
another option is to use select.select()
for non-blocking io operation.
the get_user_input
function tries to read every 0.1 sec the sys.stdin, if there is data to read it reads single byte. if it encounters a new line it returns the string.
if the timeout passed we exit returning None
the code:
import select
import sys
import time
def get_user_input(msg, timeout=5):
print(msg)
user_input = []
stime = time.time()
while time.time() - stime <= timeout:
readables, _, _ = select.select([sys.stdin], [], [], 0.1)
if not readables:
continue
chr = readables[0].read(1)
if chr == '\n':
return ''.join(user_input)
user_input.append(chr)
user_input = get_user_input('please insert something:')
if user_input is None:
print('no user input')
else:
print('input is %s' % user_input)
example output for input hello select
:
please insert something:
hello select
input is hello select
example when no input for 5 seconds:
please insert something:
no user input
if you use windows for some reason you can check out this answer about msvcrt
module.
basically its the same as select.select
for non-blocking io using msvcrt.kbhit()
to check if user returned input.
if you need more info please update about your OS.
Upvotes: 1