I want to print Text \'Loading...\' But its dots would be moving back and forward (in shell).
I am creating a text game and for that it will look b
You can use backtracking via backspace (\b
) in your STDOUT to go back and 'erase' written characters before writing them again to simulate animated loading, e.g.:
import sys
import time
loading = True # a simple var to keep the loading status
loading_speed = 4 # number of characters to print out per second
loading_string = "." * 6 # characters to print out one by one (6 dots in this example)
while loading:
# track both the current character and its index for easier backtracking later
for index, char in enumerate(loading_string):
# you can check your loading status here
# if the loading is done set `loading` to false and break
sys.stdout.write(char) # write the next char to STDOUT
sys.stdout.flush() # flush the output
time.sleep(1.0 / loading_speed) # wait to match our speed
index += 1 # lists are zero indexed, we need to increase by one for the accurate count
# backtrack the written characters, overwrite them with space, backtrack again:
sys.stdout.write("\b" * index + " " * index + "\b" * index)
sys.stdout.flush() # flush the output
Keep in mind that this is a blocking process so you either have to do your loading checks within the for
loop, or run your loading in a separate thread, or run this in a separate thread - it will keep running in a blocking mode as long as its local loading
variable is set to True
.
I believe the following code is what you are looking for. Simply thread this in your script, and it will flash dots while the user is waiting.
################################################################################
"""
Use this to show progress in the terminal while other processes are runnning
- show_running.py -
"""
################################################################################
#import _thread as thread
import time, sys
def waiting(lenstr=20, zzz=0.5, dispstr='PROCESSING'):
dots = '.' * lenstr
spaces = ' ' * lenstr
print(dispstr.center(lenstr, '*'))
while True:
for i in range(lenstr):
time.sleep(zzz)
outstr = dots[:i] + spaces[i:]
sys.stdout.write('\b' * lenstr + outstr)
sys.stdout.flush()
for i in range(lenstr, 0, -1):
time.sleep(zzz)
outstr = dots[:i] + spaces[i:]
sys.stdout.write('\b' * lenstr + outstr)
sys.stdout.flush()
#------------------------------------------------------------------------------#
if __name__ == '__main__':
import _thread as thread
from tkinter import *
root = Tk()
Label(root, text="I'm Waiting").pack()
start = time.perf_counter()
thread.start_new_thread(waiting, (20, 0.5))
root.mainloop()
finish = time.perf_counter()
print('\nYour process took %.2f seconds to complete.' % (finish - start))
A bit late but for anyone else its not that complicated.
import os, time #import os and time
def loading(): #make a function called loading
spaces = 0 #making a variable to store the amount of spaces between the start and the "."
while True: #infinite loop
print("\b "*spaces+".", end="", flush=True) #we are deleting however many spaces and making them " " then printing "."
spaces = spaces+1 #adding a space after each print
time.sleep(0.2) #waiting 0.2 secconds before proceeding
if (spaces>5): #if there are more than 5 spaces after adding one so meaning 5 spaces (if that makes sense)
print("\b \b"*spaces, end="") #delete the line
spaces = 0 #set the spaces back to 0
loading() #call the function
Check This Module Keyboard with many features. Install It, perhaps with this command:
pip3 install keyboard
Then Write the following code in File textdot.py:
def text(text_to_print,num_of_dots,num_of_loops):
from time import sleep
import keyboard
import sys
shell = sys.stdout.shell
shell.write(text_to_print,'stdout')
dotes = int(num_of_dots) * '.'
for last in range(0,num_of_loops):
for dot in dotes:
keyboard.write('.')
sleep(0.1)
for dot in dotes:
keyboard.write('\x08')
sleep(0.1)
Now Paste the file in Lib from your python folder.
Now you Can use it like following example:
import textdot
textdot.text('Loading',6,3)
Thanks