🔖
Pythonでプログレスバーを表示する
PythonとTkinterを使用してプログレスバーを表示し処理の進捗状況を表示するコードをまとめていきます
こちらのコードはChatGPTを使用して作成しています
プログレスバーを表示するコード
from tkinter import Tk, Toplevel, ttk
class ProgressBarApp:
def __init__(self, maximum):
self.root = Tk()
self.root.withdraw()
# プログレスバーのウィンドウを作成
self.progress_window = Toplevel(self.root)
self.progress_window.title("処理中")
self.progress_bar = ttk.Progressbar(self.progress_window, orient="horizontal", length=300, mode="determinate") # ①
self.progress_bar.pack(pady=20)
self.progress_bar["maximum"] = maximum # ②
# 画面の中央に表示: ③
self.progress_window.update_idletasks()
width = self.progress_window.winfo_width()
height = self.progress_window.winfo_height()
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = (screen_width // 2) - (width // 2)
y = (screen_height // 2) - (height // 2)
self.progress_window.geometry(f'{width}x{height}+{x}+{y}')
self.progress_window.deiconify()
# プログレスバーの進捗状況の表示を更新: ④
def update_progress(self, value):
self.progress_bar["value"] = value
self.progress_window.update()
# プログレスバーアプリを終了
def close(self):
self.progress_window.destroy()
self.root.quit()
コードの解説
①
ttk.Progressbarが時間のかかる作業などの進捗状況をユーザーに示すためのウィジェットを
表示するコードになります
オプションの詳しい説明は下記のサイトを参照してください
②
ここでは、プログレスバーの進捗状況がいくつになったら100%になるのかを指定します
ここで設定する数字は100である必要はなく、処理するファイルの数やデータの行数などが入ります
update_progressメソッドの引数がここで設定した数と一致すると進捗状況が100%で表示されます
③
コメントにも記載されていますが、画面中央にプログレスバーを表示するためのコードです
これを入れない場合は左上端にプログレスバーが表示されますが、
見づらく不格好なのでこのコードを作成しています
画面の縦と横のサイズとプログレスバーの縦と横のサイズから中央に表示できる座標を割り出して、
その座標に合わせてプログレスバーを表示します
④
進捗状況をprogress_bar["value"]に設定して、次の行のupdateで画面に反映しています
progress_bar["value"]に設定する値は整数である必要はなく、「3.5」などの値も設定できます
使用例
A列に数字が入っているcsvファイルから数字を集計してメッセージに表示するコード
下記のコードでは「chardet」と「pandas」のパッケージをインストールする必要があります
import chardet
import pandas as pd
import io
from tkinter import Tk, Toplevel, ttk, filedialog, messagebox
class ProgressBarApp:
def __init__(self, maximum):
self.root = Tk()
self.root.withdraw()
# プログレスバーのウィンドウを作成
self.progress_window = Toplevel(self.root)
self.progress_window.title("処理中")
self.progress_bar = ttk.Progressbar(self.progress_window, orient="horizontal", length=300, mode="determinate")
self.progress_bar.pack(pady=20)
self.progress_bar["maximum"] = maximum
# 画面の中央に表示
self.progress_window.update_idletasks()
width = self.progress_window.winfo_width()
height = self.progress_window.winfo_height()
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x = (screen_width // 2) - (width // 2)
y = (screen_height // 2) - (height // 2)
self.progress_window.geometry(f'{width}x{height}+{x}+{y}')
self.progress_window.deiconify()
# プログレスバーの進捗状況の表示を更新
def update_progress(self, value):
self.progress_bar["value"] = value
self.progress_window.update()
# プログレスバーアプリを終了
def close(self):
self.progress_window.destroy()
self.root.quit()
def process_csv_file(csv_files):
progress_app = ProgressBarApp(len(csv_files))
for file_index, csv_file in enumerate(csv_files):
# ファイルのエンコーディングを検出
with open(csv_file, 'rb') as f:
result = chardet.detect(f.read())
encoding = result['encoding']
# CSVファイルの読み込み
with open(csv_file, 'r', encoding=encoding, errors='replace') as f:
content = f.read()
data = pd.read_csv(io.StringIO(content))
total_sum = 0
for index, row in data.iterrows():
total_sum += int(row.iloc[0])
progress = index / len(data)
progress_app.update_progress(file_index + progress)
messagebox.showinfo("合計", f"合計数: {total_sum}")
progress_app.close()
# CSVファイルを選択
csv_files = filedialog.askopenfilenames(title='csvファイルを選択してください', filetypes=[("CSV", "*.csv")])
if csv_files:
process_csv_file(csv_files)
else:
messagebox.showerror("エラー", "CSVファイルが選択されていません")
Discussion