Python如何在进程运行时进行简单的动画加载

时间:2014-02-26 01:00:51

标签: python

这就是我现在所拥有的:

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” ,停止动画并将其替换为“完成!”。这种方法基本上可以同时运行两个脚本;有办法吗?

9 个答案:

答案 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:

enter image description here

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()

此外,如果您愿意使用外部库,您可能需要查看 richconsole.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 python packages

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() 

#define name of your thread

the_process = threading.Thread(name='process', target=the_process_function)

#start the thread

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)

在终端上测试并成功运行。