这就是我现在所拥有的:
import time
import sys
done = 'false'
#here is the animation
def animate():
while done == 'false':
sys.stdout.write('\rloading |')
time.sleep(0.1)
sys.stdout.write('\rloading /')
time.sleep(0.1)
sys.stdout.write('\rloading -')
time.sleep(0.1)
sys.stdout.write('\rloading \\')
time.sleep(0.1)
sys.stdout.write('\rDone! ')
animate()
#long process here
done = 'false'
我希望得到它以便“while”脚本独立运行,并且它继续进行,同时动画一直持续到过程结束,表示变量“done”为“false” ,停止动画并将其替换为“完成!”。这种方法基本上可以同时运行两个脚本;有办法吗?
答案 0 :(得分:23)
使用线程:
import itertools
import threading
import time
import sys
done = False
#here is the animation
def animate():
for c in itertools.cycle(['|', '/', '-', '\\']):
if done:
break
sys.stdout.write('\rloading ' + c)
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\rDone! ')
t = threading.Thread(target=animate)
t.start()
#long process here
time.sleep(10)
done = True
我还对您的animate()
功能进行了一些小修改,唯一非常重要的是在sys.stdout.flush()
来电后添加sys.stdout.write()
。
答案 1 :(得分:6)
从接受的答案中获得灵感,这是我写的一个有用的类,打印加载器à la nodejs cli:
from itertools import cycle
from shutil import get_terminal_size
from threading import Thread
from time import sleep
class Loader:
def __init__(self, desc="Loading...", end="Done!", timeout=0.1):
"""
A loader-like context manager
Args:
desc (str, optional): The loader's description. Defaults to "Loading...".
end (str, optional): Final print. Defaults to "Done!".
timeout (float, optional): Sleep time between prints. Defaults to 0.1.
"""
self.desc = desc
self.end = end
self.timeout = timeout
self._thread = Thread(target=self._animate, daemon=True)
self.steps = ["⢿", "⣻", "⣽", "⣾", "⣷", "⣯", "⣟", "⡿"]
self.done = False
def start(self):
self._thread.start()
return self
def _animate(self):
for c in cycle(self.steps):
if self.done:
break
print(f"\r{self.desc} {c}", flush=True, end="")
sleep(self.timeout)
def __enter__(self):
self.start()
def stop(self):
self.done = True
cols = get_terminal_size((80, 20)).columns
print("\r" + " " * cols, end="", flush=True)
print(f"\r{self.end}", flush=True)
def __exit__(self, exc_type, exc_value, tb):
# handle exceptions with those variables ^
self.stop()
if __name__ == "__main__":
with Loader("Loading with context manager..."):
for i in range(10):
sleep(0.25)
loader = Loader("Loading with object...", "That was fast!", 0.05).start()
for i in range(10):
sleep(0.25)
loader.stop()
此外,如果您愿意使用外部库,您可能需要查看 rich
的 console.status
from time import sleep
from rich.console import Console
console = Console()
tasks = [f"task {n}" for n in range(1, 11)]
with console.status("[bold green]Working on tasks...") as status:
while tasks:
task = tasks.pop(0)
sleep(1)
console.log(f"{task} complete")
答案 2 :(得分:3)
这是我的代码:
print("Loading:")
#animation = ["10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"]
animation = ["[■□□□□□□□□□]","[■■□□□□□□□□]", "[■■■□□□□□□□]", "[■■■■□□□□□□]", "[■■■■■□□□□□]", "[■■■■■■□□□□]", "[■■■■■■■□□□]", "[■■■■■■■■□□]", "[■■■■■■■■■□]", "[■■■■■■■■■■]"]
for i in range(len(animation)):
time.sleep(0.2)
sys.stdout.write("\r" + animation[i % len(animation)])
sys.stdout.flush()
print("\n")
答案 3 :(得分:1)
我看到这是一个线程问题而不仅仅是一个动画加载问题。此QA线程中提供的大多数答案仅提供伪代码并让读者自己离开。
以下是我尝试使用线程和动画加载的工作示例给出的答案。
读者可根据需要进行修改。
import sys, time, threading
# Here is an example of the process function:
def the_process_function():
n = 20
for i in range(n):
time.sleep(1)
sys.stdout.write('\r'+'loading... process '+str(i)+'/'+str(n)+' '+ '{:.2f}'.format(i/n*100)+'%')
sys.stdout.flush()
sys.stdout.write('\r'+'loading... finished \n')
def animated_loading():
chars = "/—\|"
for char in chars:
sys.stdout.write('\r'+'loading...'+char)
time.sleep(.1)
sys.stdout.flush()
the_process = threading.Thread(name='process', target=the_process_function)
the_process.start()
animated_loading()
函数while the_process.isAlive():
animated_loading()
主要步骤在注释掉的行中列出。
答案 4 :(得分:1)
from time import sleep
k='#'
j=0
k='#'
def fixed_space(i,array):
g=(' '*len(str(len(array))))
g=g.replace(' ','',len(str(int(i))))
return g
def ani(i,array):
global k
#For accessing the global variables that are defined out of the function
global j
per=((i+1)*100)//len(array)
#To calculate percentage of completion of loop
c=per//5
#Intiger division (the value 5 decides the length of the bar)
if c!=j:
#When ever the values of these 2 varavbles change add one # to the global variable k
k+='#'
y='['+k+' '+']'
#20 empty spaces (100/5)
y=y.replace(' ','',len(k))
#To make the size of the bar fixed ever time the length of k increases one ' ' will be removed
g=fixed_space(per,array)
#To fix at the same position
f=fixed_space(i,array)
print('Status : ',y,g+str(per)+'%',' ('+f+str(i+1)+' / '+str(len(array))+' ) ',end='\r')
#That same '\r' to clear previous text
j=c
array = range(100)
for i in array:
ani(i,array)
sleep(0.1)
我的代码有点乱,请随时更新
答案 5 :(得分:0)
试试这个
import time
import sys
animation = "|/-\\"
for i in range(100):
time.sleep(0.1)
sys.stdout.write("\r" + animation[i % len(animation)])
sys.stdout.flush()
#do something
print("End!")
答案 6 :(得分:0)
import sys, time, threading
def your_function_name() :
# do something here
def loadingAnimation(process) :
while process.isAlive() :
chars = "/—\|"
for char in chars:
sys.stdout.write('\r'+'loading '+char)
time.sleep(.1)
sys.stdout.flush()
loading_process = threading.Thread(target=your_function_name)
loading_process.start()
animated_loading(loading_process)
loading_process.join()
答案 7 :(得分:0)
简单的
from time import sleep #for delay
from itertools import cycle #for infinite cycling through a list
for i in cycle(["|", "/", "-", "\\"]):
print(i,end='\r') # '\r' clears the previous output
sleep(0.2)
答案 8 :(得分:-1)
所有这些只需几行代码即可完成:
import time
import os
anime = ["|", "/", "-", "\\"]
done = False
while done == False:
for i in anime:
print('Please wait while system is Loading...', i)
os.system('clear')
time.sleep(0.1)
在终端上测试并成功运行。