控制台中的文本进度条带上面的标题

时间:2017-10-15 03:37:05

标签: python console progress updating

我正在使用this答案来打印进度条 但是希望它在正在进行的过程中打印它正在做什么。 我添加了一个名为" current_task"的参数。到print_progress(),现在希望它执行如下。我该怎么做?

仅供参考:我正在使用Unix系统:macOS Sierra

print_progress(7,10,...remaining params..., "downloading contacts")

应打印此

  

目前正在下载联系人
  进展|████████████████████████████████---------------- ----- | 70%   完整

随后的

电话
print_progress(8,10,...remaining params..., "downloading companies")

应该使进度条改变到现在看起来像这样

  

目前正在下载公司   进展|████████████████████████████████████------------ - | 80%   完整

1 个答案:

答案 0 :(得分:0)

以下是Greenstick's code的修改版本,支持标题行。它使用ANSI control sequence '\x1b[3A'将终端光标向上移动3行后打印标题&进度条。

此更新版本在Python 2上正常运行(在2.6.6上测试)& Python 3(在3.6.0上测试)。它还会删除标题行的先前内容,因此如果当前标题比前一个标题短,则不会出现杂散字符。

from __future__ import print_function
from time import sleep

# Print iterations progress
#Originally written by Greensticks, modified by PM 2Ring
def printProgressBar (iteration, total, prefix='', suffix='', decimals=1, 
    length=100, fill=u'\u2588', header=''):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        header      - Optional  : header string (Str)
    """
    # Clear the current line and print the header
    print('\x1b[2K', header, '\n')
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    # Generate and print the bar
    bar = fill * filledLength + u'-' * (length - filledLength)
    print('%s |%s| %s%% %s\x1b[3A' % (prefix, bar, percent, suffix))
    # Print New Lines on Complete
    if iteration == total: 
        print('\n' * 2)

# Test

maxi = 10
delay = 0.5

# Initial call to print 0% progress
header = 'Currently downloading contacts now'
printProgressBar(0, maxi, prefix='Progress:', suffix='Complete', length=50, header=header)
for i in range(1, 8):
    # Do stuff...
    sleep(delay)
    # Update Progress Bar
    printProgressBar(i, maxi, prefix='Progress:', suffix='Complete', length=50, header=header)

header = 'Currently downloading companies'
for i in range(8, maxi + 1):
    # Do stuff...
    sleep(delay)
    # Update Progress Bar
    printProgressBar(i, maxi, prefix='Progress:', suffix='Complete', length=50, header=header)

print('Finished')

请注意,如果您不提供标题行,则会得到一个空白标题行。请确保标题行实际上适合您终端的一行,并且绝对不会在其中添加任何'\n'字符!

您可以使用threading使这个进度条更加通用,如我几个月前写的Scrolling Timer所示。

这是printProgressBar的一个版本,用于禁用光标,因此我们在光标开始时不需要额外的速度。

def printProgressBar (iteration, total, prefix='', suffix='', decimals=1, 
    length=100, fill=u'\u2588', header=''):
    """
    Call in a loop to create terminal progress bar
    @params:
        iteration   - Required  : current iteration (Int)
        total       - Required  : total iterations (Int)
        prefix      - Optional  : prefix string (Str)
        suffix      - Optional  : suffix string (Str)
        decimals    - Optional  : positive number of decimals in percent complete (Int)
        length      - Optional  : character length of bar (Int)
        fill        - Optional  : bar fill character (Str)
        header      - Optional  : header string (Str)
    """
    if iteration == 0:
        # Turn off the cursor
        print("\x1b[?25l", end='')
    # Clear the current line & print the header
    print('\x1b[2K', header, sep= '', end='\n\n')
    percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
    filledLength = int(length * iteration // total)
    # Generate and print the bar
    bar = fill * filledLength + u'-' * (length - filledLength)
    print('%s |%s| %s%% %s\x1b[3A' % (prefix, bar, percent, suffix))
    # Print New Lines on Complete
    if iteration == total: 
        # Turn on the cursor, and skip a few lines
        print("\x1b[?25h", end='\n\n')

这样做的一个问题是,如果我们在光标被禁用的同时提前终止程序(例如,通过按 Ctrl C ),它仍将被禁用程序编辑。在Linux上,您只需发送ANSI序列,即可使用简单的Bash命令重新打开光标:

echo -e "\e[?25h"

虽然重置终端更容易:

echo -e "\ec"

当然,我们也可以捕获signal.SIGINT并添加一个处理函数来在程序退出之前打开游标,但这会给代码增加额外的复杂性。