Chuyển đến nội dung chính

Thanh tiến trình trong Python: Hướng dẫn đầy đủ kèm ví dụ

Tìm hiểu cách tạo thanh tiến trình Python với tqdm, progressbar2, alive-progress và Tkinter, cùng thực hành tốt nhất để cải thiện UX và hiệu năng ứng dụng.
· 13 phút đọc

Khám phá cùng AI

Trong các ứng dụng ngày nay, người dùng muốn có phản hồi ngay lập tức, đặc biệt khi tác vụ mất nhiều thời gian để hoàn thành. Thanh tiến trình trong Python là cách rõ ràng và dễ dàng để cho thấy có điều gì đó đang diễn ra ở hậu cảnh. Một thanh tiến trình tốt giúp chương trình có cảm giác nhanh hơn, tăng tính chuyên nghiệp và thân thiện với người dùng. 

Trong bài viết này, bạn sẽ học cách triển khai thanh tiến trình Python bằng các thư viện phổ biến như tqdm, progress, progressbar2, alive-progress và Tkinter, cùng các thực hành tốt nhất để nâng cao trải nghiệm người dùng và hiệu năng ứng dụng.

Để học thêm về các khái niệm Python theo cách thực hành, hãy xem lộ trình kỹ năng Python Programming Fundamentals. 

TL;DR

  • Với công cụ dòng lệnh, tqdm là lựa chọn hàng đầu — nhẹ và hoạt động tốt với pandas. Dùng progress cho script đơn giản, progressbar2 khi cần bố cục tuỳ chỉnh, hoặc alive-progress cho hiệu ứng động.

  • Với ứng dụng desktop, ttk.Progressbar tích hợp sẵn của Tkinter xử lý cả tác vụ có thời lượng biết trước (determinate) và không xác định (indeterminate).

  • Giảm tần suất cập nhật trong vòng lặp nhanh để tránh làm chậm, và kết hợp hình ảnh với văn bản như phần trăm hoặc số đếm để thanh luôn hữu ích cho mọi người.

Thanh tiến trình trong Python là gì?

Thanh tiến trình có mặt ở khắp nơi. Chúng thường dùng cho tải tệp, cài đặt phần mềm và pipeline ETL. Chúng cũng hữu ích để theo dõi tiến độ huấn luyện mô hình machine learning.

Thanh tiến trình hiển thị phần công việc đã hoàn thành và phần còn lại. Nó có thể xuất hiện dạng văn bản trong giao diện dòng lệnh (CLI) hoặc dạng thanh trực quan trong giao diện đồ họa (GUI).

Thanh tiến trình cải thiện trải nghiệm người dùng. Chúng cung cấp cập nhật theo thời gian thực, cho thấy tiến độ của người dùng trong quy trình. Nếu có độ trễ, người dùng có thể quyết định can thiệp hay chờ. Sự minh bạch này giảm bực bội và khiến thời gian chờ có vẻ ngắn hơn. Người dùng sẽ không nhìn chằm chằm vào màn hình tĩnh và tự hỏi có gì đang diễn ra hay không; họ vẫn được kết nối và yên tâm rằng tiến trình đang diễn ra.

Nhà phát triển dùng thanh tiến trình để theo dõi hiệu năng ứng dụng. Chúng giúp xác định nút thắt cổ chai, đo benchmark cho mã và theo dõi thời lượng tác vụ. Thanh tiến trình trong script và workflow hiển thị trạng thái rõ ràng, giúp người dùng hiểu các tiến trình chạy lâu tốt hơn. Chúng cũng nâng cao tính khả dụng của công cụ tương tác và notebook.

Thanh tiến trình cũng có thể đóng vai trò giám sát hiệu năng đơn giản. Chúng cho biết mỗi tác vụ tốn bao lâu. Điều này giúp nhà phát triển phát hiện giai đoạn chậm và đo hiệu quả, cũng như so sánh dễ dàng giữa các cách triển khai. 

Thanh tiến trình cho dòng lệnh

Thanh tiến trình dòng lệnh cung cấp phản hồi trực quan cho các tác vụ chạy lâu ngay trong terminal, giúp script nhiều thông tin và thân thiện hơn. Python có vài thư viện, mỗi cái mạnh ở tốc độ, tuỳ biến và phong cách hiển thị. Chúng ta sẽ xem bốn thư viện: tqdm, progress, progressbar2 và alive-progress. 

Tqdm: tiêu chuẩn về tốc độ và đơn giản

tqdm là thư viện phổ biến trong Python để tạo thanh tiến trình. Nó cung cấp chỉ báo nhanh và linh hoạt cho vòng lặp và iterable. Nó theo dõi số lần lặp và tính thời gian còn lại lẫn đã trôi qua, cập nhật thanh theo thời gian thực. tqdm hoạt động ở hậu cảnh, dự đoán thời gian còn lại và bỏ qua các cập nhật không cần thiết. Dễ học, nhẹ bộ nhớ và có cộng đồng mạnh. 

Quy trình cài đặt

Cách dễ nhất để cài tqdm là dùng trình cài pip. Gõ lệnh sau từ terminal.

pip install tqdm

In số phiên bản để chắc chắn thư viện đã cài đúng.

import tqdm
print(tqdm.__version__)

4.67.1

Cách dùng cơ bản của tqdm

tqdm rất dễ dùng. Import thư viện. Bọc bất kỳ iterable nào với tqdm(iterable) để hiển thị thanh tiến trình.

Thay vì viết tqdm(range(n)), bạn có thể dùng dạng rút gọn trange(n) cho tiện.

from tqdm import trange
import time

for _ in trange(100, desc="Processing"):
    # Do stuff here
    time.sleep(0.05)  # simulate a task

Đoạn mã này tạo thanh tiến trình trực tiếp khi chạy.

Thanh tiến trình hiển thị

  • Phần trăm đã hoàn thành (22%)
  • Số lần lặp đã hoàn thành trên tổng số (224/1000)
  • Thời gian đã trôi qua và ước tính còn lại (đã 12 giây, còn 42 giây)
  • Số lần lặp mỗi giây (18.09 it/s).

Để thêm mô tả cho thanh, chỉ định tuỳ chọn desc.

for i in trange(1000, desc='Processing'):  # description
    # Simulate a task
    time.sleep(0.05)

Thanh tiến trình lồng nhau 

Thanh tiến trình lồng nhau trong tqdm giúp bạn theo dõi tiến độ qua nhiều vòng lặp. Chúng cũng hữu ích khi cần theo dõi nhiều giai đoạn công việc, như xử lý theo lô, vòng lặp lồng nhau, và huấn luyện mô hình. 

Bọc mỗi vòng lặp trong vòng lặp lồng nhau với tqdm. Dùng các tham số position và leave để kiểm soát cách hiển thị.

  • position: Đặt vị trí dọc của mỗi thanh tiến trình. position=0 là thanh trên cùng, position=1 ở dưới nó, v.v.
  • leave: Nếu leave=True, thanh sẽ ở lại trên màn hình sau khi xong. Nếu leave=False, nó biến mất để tránh rối.
for i in trange(3, desc='Outer loop', leave=True):
    for j in trange(5, desc='Inner loop', leave=False):
        for j in trange(4, desc='Inner inner loop', leave=False):
            time.sleep(0.05)

Thanh tiến trình lồng nhau thể hiện hệ phân cấp rõ ràng, giúp bạn hình dung các giai đoạn khác nhau của tác vụ và cung cấp thông tin chi tiết ở nhiều cấp. Điều này giúp nhà phát triển dễ dàng xác định các điểm chậm hoặc tắc nghẽn.

Tích hợp với Pandas

Tqdm tích hợp tốt với pandas. Nó cung cấp cách đơn giản để thêm thanh tiến trình cho các tác vụ trên DataFrame và series, hiển thị tiến độ thời gian thực cho các hàm như apply, groupby và map, vốn có thể chậm với bộ dữ liệu lớn.

Để bật tính năng này, gọi tqdm.pandas(). Sau đó dùng progress_apply thay cho apply thông thường của pandas. Thanh tiến trình sẽ xuất hiện khi hàm của bạn chạy qua các hàng hoặc cột. Bạn sẽ thấy tiến độ của thao tác mà không cần viết lại mã.

Trong chương trình sau, chúng ta tạo một DataFrame với cột "numbers". Cột này chứa các số nguyên từ 0 đến 1000. Sau đó ta tạo một cột mới bằng cách áp dụng thao tác "chậm" gọi là slow_squared. 

Thay vì dùng hàm apply tiêu chuẩn của pandas, ta dùng progress_apply từ tqdm. Một thanh tiến trình xuất hiện trong quá trình thực thi, cung cấp cập nhật thời gian thực về mức độ xử lý đã hoàn thành.

import pandas as pd
from tqdm import tqdm
import time

# Simulate a time-consuming operation
def slow_square(x):
    time.sleep(0.01)
    return x**2

# Create a sample DataFrame
df = pd.DataFrame({'numbers': range(1000)})

# Initialize tqdm for pandas
tqdm.pandas(desc="Processing")

# Use progress_apply instead of apply
df['slow_squared'] = df['numbers'].progress_apply(slow_square)
# Print the result
print(df.head())

Kết quả đầu ra như sau.

Ta có thể dùng progress_apply cho các thao tác DataFrame khác như groupby.

grouped = df.groupby('numbers').progress_apply(lambda g: g.sum())

Tuỳ chỉnh

Tqdm cho phép tuỳ chỉnh thanh tiến trình để phù hợp nhiều môi trường và nhu cầu. Bạn có thể điều chỉnh chiều rộng với ncols. Tham số bar_format cho bạn toàn quyền với bố cục văn bản. Ngoài ra, đặt dynamic_ncols=True giúp thanh tự động co giãn theo kích thước terminal.

Lưu ý về hiệu năng riêng với tqdm

Tqdm nhanh và nhẹ. Nó chỉ thêm rất ít độ trễ, ngay cả trong vòng lặp nhanh. Bạn có thể tắt thanh tiến trình với disable=True — hữu ích trong môi trường production nơi hiệu năng là then chốt. Với vòng lặp rất nhanh, cập nhật mỗi lần lặp có thể quá tải, nên tqdm cho phép kiểm soát tần suất cập nhật qua các tham số như mininterval và maxinterval. 

Progress: phong cách tuỳ chỉnh và spinner

Thư viện Progress trong Python cho phép bạn tạo các thanh tiến trình dạng văn bản đơn giản cho dòng lệnh. API thẳng thắn, hỗ trợ cả thanh tiến trình và spinner, cho phép tuỳ biến đầu ra cơ bản. Nhỏ gọn, nhanh và không phụ thuộc — rất phù hợp cho script nhanh và thiết lập đơn giản. 

Thư viện progress gồm bảy kiểu thanh tích hợp: Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar, IncrementalBar, PixelBar và Shadybar. 

Để cài đặt, dùng pip install.

pip install progress

Để sử dụng, import kiểu mong muốn, khởi tạo biến, dùng .next() trong vòng lặp và .finish() sau khi xong. Ví dụ, để dùng ChargingBar, dùng mã sau.

import time
from progress.bar import ChargingBar
bar = ChargingBar('Processing', max=20)
for i in range(20):
    # Do some work
    time.sleep(0.5)
    
    bar.next()
bar.finish()
`

Progress cũng bao gồm spinner cho các tác vụ có thời lượng không xác định. Mã triển khai spinner rất đơn giản.

import time
from progress.spinner import Spinner

spinner = Spinner('Processing... ')

# Spinner during a task of unknown duration.
for _ in range(50): 
    # Do stuff 
    time.sleep(0.1)  # simulate a running task

    spinner.next()

spinner.finish()

Mã này cho ra mô tả ("Processing…") kèm theo spinner.

Thư viện progress đơn giản và nhẹ, nhưng có vài hạn chế: không hỗ trợ Jupyter notebooks, không thể tự động thay đổi kích thước, và ít tuỳ chọn hơn so với tqdm. Phù hợp cho tác vụ dòng lệnh cơ bản, nhưng có thể gặp khó với công việc phức tạp hoặc yêu cầu hiệu năng cao.

Progressbar2: tuỳ biến nâng cao và tương thích tốt

Progressbar2 là thư viện Python mạnh mẽ giúp tạo thanh tiến trình linh hoạt và tuỳ chỉnh cho ứng dụng dòng lệnh. Nó có nhiều widget như phần trăm, ETA, dấu hiệu động và bộ đếm, rất phù hợp cho tác vụ CLI phức tạp hoặc cần trau chuốt. 

Progressbar2 cung cấp nhiều kiểm soát và định dạng hơn so với thư viện đơn giản như progress. Nó cũng hoạt động tốt hơn với logging và workflow đa luồng.

Để cài đặt, dùng pip install.

pip install progressbar2

Lớp ProgressBar trong progressbar2 hiển thị trạng thái tiến độ hiện tại thông qua tập hợp widget có thể tuỳ chỉnh. 

Một widget là thành phần mô-đun cập nhật dựa trên trạng thái của thanh tiến trình, bao gồm phần trăm hoàn thành, thời gian đã trôi qua và thời gian còn lại ước tính. 

Bạn có thể chọn từ nhiều loại widget: nhãn văn bản, dấu tiến trình, bộ đếm, đồng hồ, spinner và formatter tuỳ chỉnh. Sự đa dạng này cho phép bạn tuỳ biến giao diện và chức năng của thanh cho ứng dụng của mình.

Cách dùng cơ bản của Progressbar2 khá đơn giản. 

import time
import progressbar

for i in progressbar.progressbar(range(1000)):
    time.sleep(0.02)

Đầu ra hiển thị phần trăm hoàn thành, số lần lặp đã hoàn thành/tổng số, thời gian đã trôi qua và thời gian còn lại ước tính.

Các thư viện thanh tiến trình thường cập nhật một dòng trong terminal bằng ký tự trở về đầu dòng (\r). Điều này nghĩa là các lệnh print() thông thường có thể đẩy thanh xuống hoặc làm hỏng đầu ra của nó. Thư viện progressbar2 cung cấp cách in thông điệp an toàn mà không làm ảnh hưởng đến thanh tiến trình.

import time
import progressbar

bar = progressbar.ProgressBar(redirect_stdout=True)
for i in range(10):
    # Do some task
    time.sleep(0.1)

    # Print statement
    print(f'Loop #{i}')
    bar.update(i)

Thư viện progressbar2 cung cấp tuỳ biến phong phú thông qua hệ thống widget mô-đun. Widget hiển thị các chi tiết trên thanh như phần trăm hoàn thành, thời gian đã trôi qua, thời gian còn lại ước tính, bộ đếm, hoặc hoạt ảnh của thanh. Bạn có thể kết hợp các widget để tạo thanh tuỳ biến, ví dụ hiển thị phần trăm và ETA, hoặc thêm chi tiết như tên tệp, dấu thời gian, hay spinner. 

import time
import progressbar

# Define a custom set of widgets
widgets = [
    'Progress: ',                                # Description text
    progressbar.Percentage(),         # Show percentage completed
    ' ',                              
    progressbar.Bar(marker=':'),      # Custom bar with specified marker
    ' ',
    progressbar.ETA(),                    # Estimated time remaining
    ' | ',
    progressbar.Timer(),                  # Time elapsed
]

# Initialize the progress bar with widgets
bar = progressbar.ProgressBar(widgets=widgets, max_value=50)

# Task
for i in range(50):
    # Do stuff
    time.sleep(0.1)  # Simulate task
    
    bar.update(i + 1)

Alive-progress: hoạt ảnh động cho terminal hiện đại

Alive-progress hiển thị các thanh tiến trình có hoạt ảnh thay đổi theo thời gian thực, mang lại vẻ hiện đại và mượt mà cho ứng dụng dòng lệnh. Thanh di chuyển về phía trước và hiển thị các chỉ số hữu ích theo thời gian thực như phần trăm hoàn thành, thời gian đã trôi qua, thời gian còn lại ước tính và tốc độ lặp — vừa bắt mắt vừa nhiều thông tin.

Để cài thư viện alive-progress, hãy dùng pip install.

pip install alive-progress

Như trên trang GitHub của nó, để xem demo các khả năng, dùng mã sau.

from alive_progress.styles import showtime

showtime()

Bạn sẽ thấy đầu ra tương tự như sau.

Alive-progress có khả năng hiển thị và quản lý nhiều thanh tiến trình đồng thời.

from alive_progress import alive_bar
import time
import threading

# Simulate a task
def simulate_task(name, total):
    with alive_bar(total, title=name) as bar:
        for _ in range(total):
            # Do something
            time.sleep(0.5)

            bar()

# Define threads
threads = [
    threading.Thread(target=simulate_task, args=('Task A', 50)),
    threading.Thread(target=simulate_task, args=('Task B', 70)),
    threading.Thread(target=simulate_task, args=('Task C', 40)),
]

# Start each thread
for t in threads:
    t.start()

# Block the main thread until the program is finished
for t in threads:
    t.join()

Thư viện alive-progress bao gồm nhiều chủ đề tích hợp. Chủ đề điều khiển các yếu tố như kiểu hoạt ảnh, ký tự lấp đầy thanh và hiệu ứng chuyển động tổng thể. Các chủ đề phổ biến gồm classic, pulse và brackets.

import time
from alive_progress import alive_bar

with alive_bar(100, bar='blocks') as bar:
    for _ in range(100):
        # Do something
        time.sleep(0.02)
        
        bar()

Tạm dừng/tiếp tục — tạm thời dừng và tiếp tục tiến trình mà không mất trạng thái

from alive_progress import alive_bar
import time

# Run a task...
with alive_bar(100) as bar:
    for i in range(50):
        # Do something
        time.sleep(0.02)

        bar()
    
    # Pause
    bar.text('Temporarily pausing...')
    time.sleep(1)

    # Resume
    bar.text('Resuming...')
    for i in range(50):
        time.sleep(0.02)
        bar()

Thanh tiến trình GUI với Tkinter

Tkinter là bộ công cụ GUI (giao diện đồ họa) tiêu chuẩn của Python. Thiết kế có sẵn nhiều tính năng và sẵn dùng, nên bạn không cần cài thêm gì. Bạn có thể tạo cửa sổ, nút bấm, trường văn bản, menu, thanh tiến trình, v.v. Tkinter lý tưởng để xây dựng ứng dụng desktop đơn giản, công cụ tương tác và nguyên mẫu. 

Một thanh tiến trình cơ bản có thể được tạo bằng mã sau. 

import tkinter as tk
from tkinter import ttk
import time

def start_progress():
    progress["value"] = 0
    root.update_idletasks()
    for i in range(101):
        time.sleep(0.02)
        progress["value"] = i
        root.update_idletasks()

# Set up the window
root = tk.Tk()
root.title("Progress Bar")
root.geometry("300x100")

# Create a progress bar
progress = ttk.Progressbar(root, orient="horizontal", length=250, mode="determinate")
progress.pack(pady=20)

# Create a start button
start_button = ttk.Button(root, text="Start", command=start_progress)
start_button.pack()

# Start the tkinter loop
root.mainloop()

Đầu ra trên máy Mac của tôi:

Có hai chế độ với ttk.Progressbar: determinate và indeterminate. Chế độ determinate dùng khi biết thời lượng hoặc số bước của tác vụ. Chế độ indeterminate dùng khi thời lượng không rõ hoặc không thể đo theo bước.

Mã trên là cho chế độ determinate, vì ta biết độ dài tác vụ là 250 bước. Ví dụ cho chế độ indeterminate như sau.

import tkinter as tk
from tkinter import ttk
import time
import threading

def start_indeterminate():
    def run():
        # 10 ms between moves
        progress.start(10)

        # Simulate task of unknown duration
        time.sleep(10)

        # Stop
        progress.stop()
    
    # Run in a thread, else the tkinter GUI loop is unresponsive
    threading.Thread(target=run).start()

# Set up the GUI
root = tk.Tk()
root.title("Indeterminate Progress Bar")
root.geometry("300x100")

# Create an indeterminate progress bar
progress = ttk.Progressbar(root, mode='indeterminate', length=250)
progress.pack(pady=20)

# Start button
start_button = ttk.Button(root, text="Start", command=start_indeterminate)
start_button.pack()

# Run the tkinter loop
root.mainloop()

Lưu ý rằng thanh tiến trình được chạy trong luồng riêng. Nếu ta dùng run() trực tiếp ở luồng chính, lệnh time.sleep() sẽ chặn vòng lặp sự kiện chính của Tkinter và làm đông cứng toàn bộ GUI, bao gồm nhấn nút, vẽ lại cửa sổ và hoạt ảnh của thanh tiến trình.

Lưu ý hiệu năng và tối ưu hoá

Bạn nên dùng thư viện nào cho thanh tiến trình? Một phần quyết định phụ thuộc vào yêu cầu chi phí phụ trội và trường hợp sử dụng của bạn.

Thư viện

Chi phí phụ trội

Trường hợp sử dụng

tqdm

Rất thấp

Vòng lặp nhanh, pipeline dữ liệu, tác động tối thiểu đến hiệu năng

progress

Thấp

Script CLI đơn giản, nhẹ và không phụ thuộc

progressbar2

Vừa

Bố cục tuỳ chỉnh, ETA và logging; hơi chậm lại với tác vụ rất nhanh

alive-progress

Vừa đến cao

Tác vụ giàu hình ảnh, nhiều thanh đồng thời, hoạt ảnh mượt; tốt nhất cho tác vụ dài

Để nâng cao hiệu năng, hãy tối ưu tần suất cập nhật. Một phương pháp là không cập nhật thanh ở mọi lần lặp, đặc biệt trong vòng lặp nhanh hoặc tần suất cao. Dùng logic điều kiện để cập nhật mỗi N bước, ví dụ mỗi 100 lần lặp.

Trong môi trường hiệu năng nghiêm ngặt hoặc mã production, hãy tắt thanh tiến trình. Ở đây không cần phản hồi trực quan. Điều này tiết kiệm tài nguyên đồng thời giữ nguyên logic cho phát triển hoặc gỡ lỗi. 

Giảm thao tác I/O là chìa khóa cho hiệu năng. Ghi ra terminal, đĩa hoặc mạng có thể làm chậm. Dưới đây là vài chiến lược để giảm I/O trong tác vụ quan trọng về hiệu năng.

  • Đệm đầu ra và ghi theo lô thay vì mỗi lần lặp.
  • Chỉ cập nhật theo khoảng thời gian cố định hoặc khi thỏa điều kiện.
  • Giảm thiểu hoặc tắt print() bên trong vòng lặp.
  • Thêm cờ để ẩn đầu ra không cần thiết trong production.
  • Tách I/O và tính toán bằng luồng hoặc đa xử lý.
  • Nén hoặc gom các lần ghi lớn để giảm tần suất I/O đĩa.

Thực hành tốt nhất cho thanh tiến trình hiệu quả

Hãy cùng xem một số thực hành tốt nhất cần lưu ý khi tạo thanh tiến trình trong Python. 

Vì sao nên dùng thanh tiến trình?

Có nhiều lý do tốt để dùng thanh tiến trình trong ứng dụng của bạn. Thứ nhất, chúng cung cấp phản hồi theo thời gian thực, trấn an người dùng rằng tác vụ đang tiến triển và giảm sự bất định. Sự minh bạch này nâng cao trải nghiệm, khiến thời gian chờ có vẻ ngắn hơn và tương tác trực quan hơn. 

Thứ hai, bằng cách trực quan hoá mức hoàn thành, thanh tiến trình cho phép giám sát hiệu năng dễ dàng, giúp cả người dùng và nhà phát triển nhanh chóng phát hiện nút thắt hoặc tiến trình bị treo trong các thao tác chạy lâu. Cuối cùng, đưa thanh tiến trình vào nâng tầm tính chuyên nghiệp của giao diện ứng dụng, thể hiện sự rõ ràng và tư duy thiết kế lấy người dùng làm trung tâm.

Tác vụ có thời lượng biết trước và không biết trước

Dùng thanh tiến trình determinate cho tác vụ có thời lượng xác định, như xử lý tệp, vòng lặp hoặc epoch huấn luyện machine learning. Loại thanh này lấp đầy dựa trên tiến độ đo được và cho người dùng cảm nhận rõ phần việc còn lại.

Với tác vụ có độ dài không biết trước, như gọi API hoặc kiểm tra nền, dùng spinner hoặc thanh indeterminate. Chúng cung cấp dấu hiệu trực quan rằng tiến trình đang diễn ra, ngay cả khi ta không thể dự đoán mất bao lâu.

Nên dùng thư viện nào?

Thư viện bạn dùng phụ thuộc vào tác vụ bạn muốn hoàn thành.

Tác vụ 

Thư viện

Ghi chú

Vòng lặp tần suất cao

tqdm

Nhẹ, hiệu quả; dùng mininterval để giảm cập nhật

Script đơn lẻ đơn giản

progress

Thiết lập tối thiểu, không phụ thuộc, lý tưởng cho tác vụ nhanh

Đầu ra có cấu trúc/tuỳ chỉnh

progressbar2

Dựa trên widget, hỗ trợ ETA, timer và kiểm soát bố cục

Tác vụ nhiều giai đoạn hoặc lồng nhau

tqdm, alive-progress

Hỗ trợ thanh lồng nhau hoặc hiển thị nhiều thanh cho tác vụ nhiều lớp

Script CLI cần trau chuốt hình ảnh

alive-progress

Hình ảnh động hiện đại, trải nghiệm người dùng mượt

Ứng dụng GUI

tkinter

Bộ công cụ GUI tích hợp với thanh determinate và indeterminate

Tuỳ chỉnh

Khi tuỳ chỉnh thanh tiến trình, hãy tập trung vào sự rõ ràng và thông tin hữu ích, cân bằng giữa hai yếu tố. Một thanh đơn giản, rõ ràng với các chỉ số chính thường tốt hơn một thanh bị nhồi nhét quá nhiều thông tin. 

Bạn có thể dùng các thư viện như progressbar2 và alive-progress để thay đổi bố cục, màu sắc và hoạt ảnh của thanh. Dùng chủ đề hoặc định dạng để cải thiện trải nghiệm. Tránh làm rối màn hình với quá nhiều widget hoặc hình ảnh phức tạp. Mục tiêu là cung cấp phản hồi hữu ích, tránh gây xao nhãng hay quá tải cho người dùng.

Xử lý ngoại lệ và kiểm thử tương thích

Bọc logic thanh tiến trình trong các khối try-except để tránh lỗi giao diện hoặc sập ứng dụng nếu có lỗi xảy ra trong quá trình thực thi. Điều này rất quan trọng với script chạy lâu hoặc khi dùng phụ thuộc ngoài không chắc chắn.

Đồng thời, hãy kiểm thử thanh tiến trình trong các môi trường khác nhau: hệ điều hành, loại terminal, và độ rộng hiển thị. Như vậy, bạn đảm bảo hành vi nhất quán.

Một số thư viện có hành vi khác nhau trong Jupyter notebooks, terminal từ xa hoặc shell GUI. Xác minh tương thích sớm giúp tránh sự cố bất ngờ, mang lại trải nghiệm mượt mà hơn trong production.

Lưu ý về khả năng tiếp cận

Khi tạo chỉ báo tiến độ, hãy cân nhắc khả năng tiếp cận để mọi người dùng đều nhận được phản hồi rõ ràng. Một số gợi ý:

  • Đừng chỉ dựa vào màu sắc hoặc hoạt ảnh để thể hiện tiến độ. Thêm yếu tố văn bản như phần trăm, số bước hoặc ước tính thời gian.
  • Dùng hình ảnh rõ ràng, độ tương phản cao để dễ đọc.
  • Đảm bảo thanh tiến trình hoạt động tốt với trình đọc màn hình trong ứng dụng GUI.
  • Với công cụ dòng lệnh, cân nhắc tuỳ chọn độ chi tiết (verbosity) để in cập nhật tiến độ bằng văn bản thuần.

Ưu tiên khả năng tiếp cận sẽ tăng tính khả dụng, đồng thời giúp công cụ của bạn bao trùm và chuyên nghiệp hơn.

Kết luận 

Thanh tiến trình là tính năng đơn giản nhưng mạnh mẽ cho mọi ứng dụng Python. Chúng mang lại phản hồi tức thời, cải thiện trải nghiệm người dùng, đồng thời hỗ trợ theo dõi hiệu năng và độ rõ ràng của mã. Việc chọn đúng thư viện thanh tiến trình là chìa khóa để nâng tầm phần mềm của bạn, dù bạn đang tạo script nhanh, công cụ dòng lệnh hay ứng dụng GUI đầy đủ. Một triển khai có suy nghĩ kỹ sẽ nâng cao tốc độ, tính chuyên nghiệp và mức độ thân thiện. Ưu tiên tuỳ chỉnh, hiệu năng, tương thích và khả năng tiếp cận sẽ biến thanh tiến trình thành phần cốt lõi trong cách người dùng tương tác với sản phẩm của bạn, chứ không chỉ là yếu tố hình ảnh.

Để tiếp tục học, hãy tham khảo các tài nguyên sau:

Câu hỏi thường gặp về thanh tiến trình Python

Thanh tiến trình là gì?

Thanh tiến trình là chỉ báo trực quan cho biết một tác vụ đã hoàn thành bao nhiêu và còn lại bao nhiêu. Nó cải thiện trải nghiệm người dùng bằng cách cung cấp phản hồi trong các thao tác kéo dài.

Những thư viện thanh tiến trình phổ biến trong Python là gì?

Các thư viện phổ biến nhất là tqdm, progress, progressbar2 và alive-progress.

Tôi có thể dùng thanh tiến trình với thư viện pandas không?

Có. tqdm tích hợp với pandas thông qua progress_apply() (thay cho apply) và các phương thức tương tự.

Tôi có thể tuỳ chỉnh giao diện của thanh tiến trình không?

Có. Các thư viện như tqdm và progressbar2 cho phép tuỳ chỉnh bố cục, độ rộng, màu sắc và tần suất cập nhật.

Tôi nên dùng thư viện nào cho Jupyter Notebooks.

Thư viện tqdm.notebook tích hợp tốt với Jupyter.

Mark Pedigo

Tác giả

Mark Pedigo

Mark Pedigo, PhD, là một nhà khoa học dữ liệu xuất sắc với chuyên môn về khoa học dữ liệu trong y tế, lập trình và giáo dục. Với bằng Tiến sĩ Toán học, Cử nhân Khoa học Máy tính và Chứng chỉ Chuyên nghiệp về AI, Mark kết hợp hiểu biết kỹ thuật với khả năng giải quyết vấn đề thực tiễn. Sự nghiệp của anh bao gồm các vai trò trong phát hiện gian lận, dự đoán tử vong ở trẻ sơ sinh và dự báo tài chính, cùng với những đóng góp cho phần mềm ước tính chi phí của NASA. Là một nhà giáo dục, anh đã giảng dạy tại DataCamp và Đại học Washington ở St. Louis, đồng thời cố vấn cho các lập trình viên trẻ. Trong thời gian rảnh, Mark thích hoạt động ngoài trời ở Minnesota cùng vợ là Mandy và chú chó Harley, và chơi piano jazz.

Chủ đề

Liên quan