Python×Tkinter環境で、プログレスバーのモーダルダイアログを出したいときのコード。画像のように、別ウィンドウでプログレスバーを出してみた。
とりあえず完全なコード。
コード全体
import tkinter as tk
from tkinter import ttk
from time import sleep
class ProgressDialog:
def __init__(self, parent):
self.parent = parent
self.dialog = tk.Toplevel(parent)
self.dialog.title("Progress")
self.dialog.geometry("300x100")
self.label = ttk.Label(self.dialog, text="")
self.label.grid(row=0, column=1, padx=5, pady=5, sticky="we")
self.progress_bar = ttk.Progressbar(self.dialog, maximum=1)
self.progress_bar.grid(row=1, column=1, padx=5, pady=5, sticky="we")
self.dialog.transient(parent)
self.dialog.grab_set() # ダイアログにフォーカス
self.dialog.columnconfigure(0, weight=1)
self.dialog.columnconfigure(1, weight=4)
self.dialog.columnconfigure(2, weight=1)
self.dialog.rowconfigure( 0, weight=1)
self.dialog.rowconfigure( 1, weight=1)
self.dialog.rowconfigure( 2, weight=1)
def close(self):
self.dialog.destroy() # ダイアログを破棄
# プログレスバーとラベルを更新
def update_pg(self, total, current):
self.progress_bar.configure(value=(current/total))
self.progress_bar.update()
self.label.configure(text= "処理中... " + str(current) + "/" + str(total))
self.label.update()
def main():
root = tk.Tk()
root.title("Main Window")
def show_progress_dialog():
progress_dialog = ProgressDialog(root)
count = 10
for i in range(count):
progress_dialog.update_pg(total=count, current=i)
# ここにプログレスバーダイアログを表示したい処理を挿入
sleep(1)
progress_dialog.close()
button = tk.Button(root, text="Show Progress", command=show_progress_dialog)
button.pack(pady=20)
root.mainloop()
if __name__ == "__main__":
main()
main関数の中では重たい処理兼ProgressDialogを呼び出すボタンを備えたメインウィンドウを表示している。ProgressDialogクラスはプログレスバーを含んだTopLevelウィンドウをダイアログチックに表示する。ProgressDialog自体も普通にGridでレイアウトしているので、見た目を変えたければdef init(self, parent):
の中をいじると良い。
以下使う場合に呼び出す関数。
progress_dialog = ProgressDialog(root)
ダイアログの表示を行う。引数には親のウィンドウウィジェットを渡す。
progress_dialog.update_pg(total=count, current=i)
プログレスバーを進める。totalには処理件数の総数、currentには処理が完了した総数を渡す。
progress_dialog.close()
処理が終わったらダイアログをクローズする。