Question:
I’m trying to make a typing effect in the terminal paired with an input(). I found some code online (snippet below) and tried it. It worked, it had the typing effect and the input worked. Kind of. If I typed a little into the input, and then held backspace, it would delete the text from the typing effect!



Repl link:
https://replit.com/@TinyMooshmallow/imbadatpython
Typing effect code?
import sys
import time
def tinput(text):
for character in text:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.05)
value = input("")
return value
2 Likes
Hey @TinyMooshmallow!
I believe when you use sys
it counts as normal user inputted text, therefore you can delete it, whereas if it’s text from the program (like normal inputs) it’s text can’t be deleted. (I might be totally wrong, if so point it out)
2 Likes
It’s because you are using sys.stdout.write()
and input()
.
When you call input()
, the terminal cursor goes back to the line where the output from sys.stdout.write()
is… If you use backspace, it will erase the characters on this line.
You can fix this by printing a newline character, like this:
import sys
import time
def tinput(text):
for character in text:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.05)
sys.stdout.write('\n') # Print a newline character
value = input()
return value
4 Likes
Yeah but I don’t want to make another line. I want it to be like a normal input, just with the typing effect. Is that possible?
1 Like
Hmmm
It’s possible but without the sys.stdout
. You can use the print()
function with the end
parameter set to an empty string (''
).
Kinda like this:
import time
def tinput(text):
for character in text:
print(character, end='', flush=True)
time.sleep(0.05)
value = input()
return value
(flush=true and stdout.flush is kinda like the same)
1 Like
Even with print(), I’m still getting the same problem?
1 Like
Strange…
Try using ANSI.
I found this googling:
Adapting to your code will be something like this:
import sys
import time
from colorama import Fore, Style
def tinput(text):
for character in text:
sys.stdout.write(character)
sys.stdout.flush()
time.sleep(0.05)
sys.stdout.write('\n')
value = input()
sys.stdout.write('\x1b[1A')
return value
tinput(Fore.CYAN + "Username: " + Style.RESET_ALL)
2 Likes
The code causes really weird behavior. When I press enter on the input, some of the text becomes “ghost text” that you can’t delete and when you type over them and backspace they disappear?
I created a new project and tried some things…
I found out about readline so I think this will work in your case.
import time
from colorama import Fore, Style
import readline
def tinput(text):
for character in text:
print(character, end='', flush=True)
time.sleep(0.05)
readline.set_startup_hook(lambda: readline.insert_text(''))
value = input()
readline.set_startup_hook()
return value
tinput(Fore.CYAN + "Username: " + Style.RESET_ALL)
1 Like
It still didn’t work? When deleting the last character in the input, it simply removes all of the text earlier.
UPDATE: I figured out that when putting ANY string containing something in the input, it works? I’m not sure why though. Also I tried using the zero-width non-joiner in the string to cheat it but that didn’t work.
this function might help you
from os import system
from time import sleep
def type_text(text):
for i in range(len(text)):
print(text[0:i+1])
sleep(0.5)
system("clear")
…no, it doesn’t. look at the other comments please