杰瑞科技汇

Python中如何实现进度条?

Of course! A progress bar is a crucial tool for any script that takes a long time to run, as it provides visual feedback to the user, letting them know the program is still working and how much is left.

Here’s a comprehensive guide to using progress bars in Python, covering the most popular libraries and from simple to advanced examples.


The Quick and Easy Answer: tqdm

For 99% of use cases, tqdm (which means "progress" in Arabic) is the best choice. It's incredibly easy to use, highly customizable, and works seamlessly in scripts, notebooks, and even command-line pipes.

Installation

First, you need to install it:

pip install tqdm

Basic Usage

The simplest way to use tqdm is to wrap any iterable (like a list or a range) with it.

from tqdm import tqdm
import time
# A simple loop
for i in tqdm(range(100)):
    time.sleep(0.05) # Simulate work

Running this will produce a nice progress bar in your terminal:

100%|██████████| 100/100 [00:05<00:00, 19.50it/s]

Real-World Example: Downloading Files

A very common use case is showing progress during a file download. The requests library is perfect for this.

import requests
from tqdm import tqdm
url = "https://speed.hetzner.de/100MB.bin" # A 100MB test file
response = requests.get(url, stream=True)
# Get the total file size from headers
total_size_in_bytes = int(response.headers.get('content-length', 0))
block_size = 1024 # 1 Kibibyte
# Wrap the response.iter_content with tqdm
progress_bar = tqdm(total=total_size_in_bytes, unit='iB', unit_scale=True, desc="Downloading")
with open("100MB.bin", "wb") as file:
    for data in response.iter_content(block_size):
        progress_bar.update(len(data))
        file.write(data)
progress_bar.close()

Key Features of tqdm

  • Automatic Updates: It figures out the iteration count and speed automatically.
  • Context Managers: You can use it with with statements for more control.
  • Nested Bars: It supports nested loops with sub-bars.
  • Notebook Integration: It works beautifully in Jupyter and Google Colab notebooks, creating a rich HTML progress bar.
  • Pipes: It can monitor the progress of data being piped through a command-line script.

The Built-in Solution: print()

If you can't install external libraries, you can always create a simple text-based progress bar using just print(). This is great for simple scripts or learning purposes.

import time
def simple_progress_bar(current, total, bar_length=20):
    percent = float(current) * 100 / total
    arrow = '-' * int(round(percent / 100 * bar_length)-1) + '>'
    spaces = ' ' * (bar_length - len(arrow))
    # The '\r' character moves the cursor to the beginning of the line
    print(f"Progress: [{arrow}{spaces}] {percent:.2f}%", end='\r')
total_items = 100
for i in range(total_items + 1):
    simple_progress_bar(i, total_items)
    time.sleep(0.05)
# Print a newline at the end to move to the next line
print("\nDone!")

How it works:

  1. \r (Carriage Return): This is the magic character. It moves the cursor back to the start of the current line without moving down. The end='\r' argument in print() prevents it from adding a newline character.
  2. The Bar: We calculate how much of the bar should be filled (arrow) and how much should be empty (spaces).
  3. end='\r': This ensures that the next print() call overwrites the current line, creating the illusion of a moving bar.

The GUI Solution: tqdm with rich

If you're building a desktop application or want a beautiful, rich-text progress bar in your terminal, the rich library is an excellent choice. It can also be used as a backend for tqdm.

Installation

pip install rich

Usage

rich has its own progress manager that is very powerful.

from rich.progress import Progress
import time
# Rich has its own context manager for progress bars
with Progress() as progress:
    # Add a task to the progress bar
    task = progress.add_task("[cyan]Processing...", total=100)
    for i in range(100):
        # Simulate work
        time.sleep(0.05)
        # Update the progress bar
        progress.update(task, advance=1)

This will produce a stunning, colorful, and informative progress bar directly in your terminal.

You can also use tqdm with the rich backend:

from tqdm import tqdm
from rich.progress import BarColumn, TextColumn, TimeRemainingColumn
# Create a custom tqdm bar using rich components
bar_format = "{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}]"
with tqdm(range(100), bar_format=bar_format, colour="green") as pbar:
    for i in pbar:
        time.sleep(0.05)

For GUI Applications: PyQt or Tkinter

If you are building a graphical user interface (GUI) with a framework like PyQt or Tkinter, you would use their native widgets.

Tkinter Example

Tkinter is Python's built-in GUI library.

import tkinter as tk
from tkinter import ttk
import time
def run_task():
    progress_bar['value'] = 0
    for i in range(101):
        # Simulate work
        time.sleep(0.05)
        progress_bar['value'] = i
        # Update the window to show the progress
        root.update_idletasks()
# Create the main window
root = tk.Tk()"Tkinter Progress Bar")
root.geometry("300x100")
# Create a progress bar widget
progress_bar = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate")
progress_bar.pack(pady=20)
# Start the task in a way that doesn't freeze the GUI
# (For a real app, you'd use threading)
run_task()
root.mainloop()

PyQt5/PySide2 Example

PyQt is a more powerful and modern GUI framework.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QProgressBar, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtCore import QThread, pyqtSignal
import time
# Worker thread to perform the task without freezing the GUI
class Worker(QThread):
    progress_updated = pyqtSignal(int)
    def run(self):
        for i in range(101):
            time.sleep(0.05)
            self.progress_updated.emit(i)
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt Progress Bar")
        self.setGeometry(100, 100, 300, 150)
        self.progress_bar = QProgressBar()
        self.button = QPushButton("Start Task")
        self.button.clicked.connect(self.start_task)
        layout = QVBoxLayout()
        layout.addWidget(self.progress_bar)
        layout.addWidget(self.button)
        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)
    def start_task(self):
        self.button.setEnabled(False)
        self.progress_bar.setValue(0)
        self.worker = Worker()
        self.worker.progress_updated.connect(self.progress_bar.setValue)
        self.worker.finished.connect(self.task_finished)
        self.worker.start()
    def task_finished(self):
        self.button.setEnabled(True)
        print("Task finished!")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

Summary: Which One Should You Use?

Scenario Recommended Tool Why?
Simple script, command line tqdm Easiest to use, just wrap an iterable. Looks great by default.
Cannot install packages print() with \r Built-in, no dependencies. Good for basic needs.
Terminal app with rich UI rich Creates beautiful, colorful, and informative bars.
Jupyter Notebook / Colab tqdm Works out-of-the-box with a rich HTML display.
Desktop GUI App PyQt/Tkinter widgets The standard way to integrate progress into a graphical interface.
Advanced logging & CLI rich More than just a progress bar; it's a full-f rich text and formatting library.

For any new project, start with tqdm. It's the industry standard for a reason.

分享:
扫描分享到社交APP
上一篇
下一篇