小能豆

在控制台中重写多行

javascript

我知道可以用“\r”一致地重写终端上显示的最后一行,但我无法弄清楚是否有办法返回并编辑控制台中打印的先前的行。

我想做的是重印多行用于基于文本的 RPG,然而,我的一位朋友也对此感到疑惑,因为有一个应用程序,其中一行专用于进度条,另一行描述下载。

即控制台将打印:

Moving file: NameOfFile.txt  
Total Progress: [########              ] 40%

然后在程序运行时进行适当的更新(对两行)。


阅读 37

收藏
2024-08-26

共1个答案

小能豆

要在控制台中更新之前打印的多行,你可以使用 ANSI 转义序列来移动光标并重新打印行。以下是一个示例,演示如何在控制台中实现这一点,这适用于更新进度条和其他动态信息。

示例代码

下面的 Python 示例代码展示了如何在控制台中更新多行:

import sys
import time

def print_progress_bar(progress, total):
    percent = (progress / total) * 100
    bar_length = 40
    filled_length = int(bar_length * progress // total)
    bar = '#' * filled_length + '-' * (bar_length - filled_length)
    return f"[{bar}] {percent:.0f}%"

def main():
    file_name = "NameOfFile.txt"
    total_steps = 100

    for i in range(total_steps + 1):
        # Move the cursor up 2 lines
        sys.stdout.write("\033[F\033[F")

        # Print the updated lines
        sys.stdout.write(f"Moving file: {file_name}\n")
        sys.stdout.write(f"Total Progress: {print_progress_bar(i, total_steps)}\n")

        # Flush the output to make sure it's updated immediately
        sys.stdout.flush()

        # Simulate some work with a sleep
        time.sleep(0.1)

if __name__ == "__main__":
    main()

解释

  1. ANSI 转义序列 "\033[F": 这是一个控制光标移动的转义序列,其中 \033 是转义字符,F 是“上移一行”的指令。通过重复使用 \033[F\033[F,你可以将光标上移两行。

  2. sys.stdout.write: 使用 sys.stdout.write 来写入内容而不自动换行,这允许你在同一位置覆盖以前的内容。

  3. sys.stdout.flush(): 确保输出立即刷新到控制台,以便更改能够即时显示。

  4. time.sleep(0.1): 模拟工作过程的延迟,使进度条的更新更为明显。

注意事项

  • 终端兼容性: ANSI 转义序列在大多数现代终端中都受支持,但某些旧版或非标准终端可能不支持。确保你的终端支持这些转义序列。

  • 跨平台: 上述代码适用于 Unix-like 系统。对于 Windows,ANSI 转义序列的支持情况可能不同。现代版本的 Windows 10 的终端通常支持 ANSI 转义序列,但较旧版本可能不支持。

在 Windows 上使用

如果你在旧版本的 Windows 上运行代码,可能需要使用 colorama 库来启用 ANSI 转义序列:

pip install colorama

然后在代码中初始化 colorama

import sys
import time
import colorama
from colorama import Cursor

colorama.init()

def print_progress_bar(progress, total):
    percent = (progress / total) * 100
    bar_length = 40
    filled_length = int(bar_length * progress // total)
    bar = '#' * filled_length + '-' * (bar_length - filled_length)
    return f"[{bar}] {percent:.0f}%"

def main():
    file_name = "NameOfFile.txt"
    total_steps = 100

    for i in range(total_steps + 1):
        # Move the cursor up 2 lines
        sys.stdout.write(f"{Cursor.UP(2)}")

        # Print the updated lines
        sys.stdout.write(f"Moving file: {file_name}\n")
        sys.stdout.write(f"Total Progress: {print_progress_bar(i, total_steps)}\n")

        # Flush the output to make sure it's updated immediately
        sys.stdout.flush()

        # Simulate some work with a sleep
        time.sleep(0.1)

if __name__ == "__main__":
    main()

通过这些方法,你可以在控制台中动态更新多行内容,适用于文本游戏、进度条显示和其他实时更新需求。

2024-08-26