I would like to have a timer above an input, then end the timer once the player inputs anything.
So far I've tried using threading and sys.flush, and multithreading to terminate the thread, but I wasn't able to input anything since the timer just followed the cursor.
My Code:
def DisplayTime():
import sys
while True:
sys.stdout.write('\r' str(format_time))
sys.stdout.flush()
displayTime = threading.Thread(name='DisplayTime', target=DisplayTime)
Somewhere else:
displayTime.start()
What happened:
>>> Text Here
>>> Timer: 0:00:00(Wait for input)
I was expecting something like this:
>>> Timer: 0:00:00
>>> Text Here
>>> (Wait for input)
>>> Timer: 0:00:01
>>> Text Here
>>> (Wait for input)
CodePudding user response:
The following code prints a timer followed by a line of text followed by an empty line on which the cursor is displayed. start_time
lets us calculate the elapsed time, and last_printed
keeps track of the last printed time so we don't have to print on every iteration. The important parts are taken from other StackOverflow answers:
import sys
import time
import msvcrt
import datetime
start_time = time.time()
last_printed = -1
print('\n')
while True:
elapsed_time = time.time() - start_time
int_elapsed = int(elapsed_time)
if int_elapsed > last_printed:
elapsed_td = datetime.timedelta(seconds=int_elapsed)
# Go up one line: https://stackoverflow.com/a/11474509/20103413
sys.stdout.write('\033[F'*2 str(elapsed_td) '\nText here\n')
sys.stdout.flush()
last_printed = int_elapsed
# Non-blocking input: https://stackoverflow.com/a/2409034/20103413
if msvcrt.kbhit():
print(msvcrt.getch().decode())
break