windows 其他打印语句中的进度条不起作用-找不到有用的进度条

inkz8wg9  于 2023-04-22  发布在  Windows
关注(0)|答案(1)|浏览(168)

简介(骑在星际办公椅上)

我有一个程序,它使用进度条来显示最终用户程序是否工作。这应该告诉最终用户他们需要等待多长时间以及程序是否仍在工作。这个问题是在阅读这个有趣的堆栈溢出线程后提出的:Text progress bar in terminal with block characters

问题/挑战

第一个问题是进度条目前只在一个循环中工作,只打印出范围内的数字。这是没有帮助的。为什么有人想要一个进度条只显示单个循环的进度,而不是程序的其余部分正在做什么的程序。
第二个问题是,当我有其他打印语句与进度条有突然多个进度条打印到命令提示符,而不是一个单一的进度条,似乎动画与每个进度条更新。
我怎样才能让进度条总是在终端的底部,而其他的打印语句在它上面呢?
另一个挑战是我正在使用Windows 7操作系统(OS)。

编码

请查看我为您提供的以下示例代码:

import sys
import time
import threading

def progress_bar(progress):
    sys.stdout.write('\r[{0}] {1}'.format('#' * int(progress/10 * 10), progress))

def doThis():
    for i in range(10):
        print("Doing this.")

def doThat():
    for i in range(3):
        print("Doing that.")

def wrapUp():
    total = 2+ 2
    print("Total found")
    return total
         
if __name__ == "__main__":
  print("Starting in main...")
  progress_bar(1)
  print("\nOther print statement here.")
  print("Nice day, expensive day.")
  progress_bar(3)

  doThis()
  progress_bar(4)
  doThat()
  progress_bar(5)
  doThis()
  doThat()
  progress_bar(6)
  progress_bar(7)
  doThat()
  doThat()
  progress_bar(8)
  wrapUp()
  progress_bar(9)
  progress_bar(10)

程序打印的内容

Starting in main...
[#] 1
Other print statement here.
Nice day, expensive day.
[###] 3Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
[####] 4Doing that.
Doing that.
Doing that.
[#####] 5Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
[#######] 7Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
[########] 8Total found
[##########] 10
zzwlnbp8

zzwlnbp81#

你必须做三件事:

  • 将进度条状态存储在一个单独的对象中,你可以在不同的循环中调用方法来更新进度条状态。
  • 打印进度条时,确保不打印换行符
  • 打印控制台输出时,先清除当前行,打印后重新绘制条形图。

你可以稍微涵盖前两个,但不包括第三个。最好将控制台的控制封装在一个类中,这个类也可以管理进度条,这样它就可以在一个位置处理清除、打印和重新显示:

import builtins
import math
import sys
import threading

class ProgressConsole:
    def __init__(self, size, width=80, output=sys.stdout):
        self.size = size
        self.width = width
        self.current = 0
        self.output = output
        # [...] and space take 3 characters, plus max width of size (log10 + 1)
        self._bar_size = width - 4 - int(math.log10(size))
        self._bar_step = self._bar_size / self.size
        self._lock = threading.Lock()

    def print(self, *message):
        with self._lock:
            self._clear()
            builtins.print(*message, file=self.output)
            self._display()

    def increment(self, step=1):
        with self._lock:
            self.current = min(self.current + step, self.size)
            self._display()

    def _clear(self):
        self.output.write('\r')
        self.output.write(' ' * self.width)
        self.output.write('\r')

    def _display(self):
        bar = '#' * int(round(self._bar_step * self.current))
        blank = ' ' * (self._bar_size - len(bar))
        self.output.write(f"\r[{bar}{blank}] {self.current}")

我在示例代码导入threading时包含了一个线程锁,因此我假设您希望能够在这样的环境中使用它。
上面的类使用固定宽度的进度条,在返回到最左边的列\r之前,通过写出一系列空格来清除进度条。
我还将条形图设置为固定宽度,以便它从左到右填充,而不是在屏幕上扩展。
然后确保你'打印'到这个对象:

if __name__ == "__main__":
    progress_bar = ProgressConsole(10)
    print = progress_bar.print  # replace built-in with our own version

    print("Starting in main...")
    progress_bar.increment()
    print("\nOther print statement here.")
    print("Nice day, expensive day.")
    progress_bar.increment(2)

    doThis()
    progress_bar.increment()
    doThat()
    progress_bar.increment()
    doThis()
    doThat()
    progress_bar.increment(2)
    doThat()
    doThat()
    progress_bar.increment()
    wrapUp()
    progress_bar.increment(2)

上面的最终输出是:

Starting in main...

Other print statement here.
Nice day, expensive day.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing this.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Doing that.
Total found
[###########################################################################] 10

插入一些随机睡眠,运行时看起来像这样:

相关问题