简体   繁体   English

带有标题的控制台中的文本进度栏

[英]Text Progress Bar in Console w/ title above

I am using this answer to print a progress bar but want it to print what exactly it is doing while it is progressing. 我正在使用答案来打印进度条,但希望它在进度条上打印其确切功能。 I added a parameter called "current_task" to print_progress() and now would like it to perform as follows. 我在print_progress()中添加了一个名为“ current_task”的参数,现在希望它执行如下操作。 How do I do this? 我该怎么做呢?

FYI: I'm on on a Unix system: macOS Sierra 仅供参考:我使用的是Unix系统:macOS Sierra

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

should print this 应该打印这个

Currently downloading contacts 当前正在下载联系人
Progress |████████████████████████████████---------------------| 进度|█████████████████████████████████---------------- ----- | 70% Complete 70%完成

the subsequent call of 随后的呼叫

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

should cause the progress bar to change in place to now look like this 应该导致进度条改变到现在的样子

Currently downloading companies 目前正在下载的公司
Progress |████████████████████████████████████-------------| 进度|█████████████████████████████████████------------ - | 80% Complete 完成80%

Here's a modified version of Greenstick's code that supports a header line. 这是支持标题行的Greenstick代码的修改版本。 It uses an ANSI control sequence '\\x1b[3A' to move the terminal cursor up 3 lines after it's printed the header & progress bar. 在打印标题和进度条后,它使用ANSI控制序列 '\\x1b[3A'将终端光标向上移动3行。

This updated version works correctly on Python 2 (tested on 2.6.6) & Python 3 (tested on 3.6.0). 此更新版本可在Python 2(在2.6.6上测试)和Python 3(在3.6.0上测试)上正常运行。 It also erases the previous contents of the header line so you don't get stray characters if the current header is shorter than the previous one. 它还会擦除标题行的前一个内容,因此,如果当前标题比前一个短,则不会出现杂散字符。

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

Note that if you don't supply a header line you'll get a blank header line. 请注意,如果您不提供标题行,则将获得空白标题行。 Please make sure that the header line will actually fit on one line of your terminal, and definitely don't put any '\\n' chars in it! 请确保标题行实际上适合您终端的一行,并且绝对不要在其中放置任何'\\n'字符!


You could make this progress bar more versatile by using threading , as illustrated in this Scrolling Timer I wrote a few months ago. 您可以通过使用threading来使此进度栏更加通用,如我几个月前编写的Scrolling Timer中所示。


Here's a version of printProgressBar that disables the cursor so we don't need that extra pace at the start of the cursor. 这是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')

One problem with doing this is that if we terminate the program early (eg by hitting Ctrl C ) while the cursor is disabled, it will still be disabled after the program edits. 这样做的一个问题是,如果在禁用光标的情况下提早终止程序(例如, 按Ctrl C ),则在程序编辑后仍将禁用该程序。 On Linux, you can just send the ANSI sequence to turn the cursor back on with a simple Bash command: 在Linux上,您只需发送ANSI序列即可使用简单的Bash命令重新打开光标:

echo -e "\e[?25h"

although it's easier to reset the terminal: 尽管重置终端更容易:

echo -e "\ec"

Of course, we could also trap signal.SIGINT and add a handler function to turn the cursor on before the program exits, but that adds extra complexity to the code. 当然,我们也可以捕获signal.SIGINT并添加一个处理程序函数以在程序退出之前打开光标,但这会增加代码的复杂性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM