2
6

[Python][tkinter] forループ数に応じたプログレスバーのシンプルな表示方法

Last updated at Posted at 2023-02-23

作ったプログラムの備忘録

はじめに

for文でフォルダ内にあるファイル数分だけ処理をまわすときに、tkinterに進捗状況を表示したかったのでttk.Progressbarの動かし方を調べたところ、思った挙動がなかなか得られませんでした。

たとえば以下のようなサイトにあるコードなども転記してみたりしましたが、いまいち関数で外に出している意味やafter関数が重なったif文など腑に落ちない状態でした。

というわけで、狙いの挙動を得るのに必要なコードについて検討したところ、シンプルな表記ができたのでメモとして記載します。

実行環境

Windows 10 Pro 64bit
Python 3.9.13

プログレスバー表示に必要なコード

実際に動く最小コード
実際に動く最小コード
import time
import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title("プログレスバー")

# プログレスバー配置
progbar = ttk.Progressbar(root, length=400, mode="determinate", maximum=1)
progbar.pack()

# for文を回すリスト
prog_list = list('abcdefghijklmnopqrstuvwxyz')

# ループ処理
for i in range(len(prog_list)):
    time.sleep(0.05)
    # プログレスバー表示変更
    progbar.configure(value=(i+1)/len(prog_list))
    progbar.update()

root.mainloop()
プログレスバー表示に関する部分の抜粋
# プログレスバー配置
progbar = ttk.Progressbar(root, length=400, mode="determinate", maximum=1)
progbar.pack()

# for文を回すリスト
prog_list = list('abcdefghijklmnopqrstuvwxyz')

# ループ処理
for i in range(len(prog_list)):
    # -- ここに処理を記載 # 例:time.sleep(0.05)
    # プログレスバー表示変更
    progbar.configure(value=(i+1)/len(prog_list))
    progbar.update()
  • 最初の2行はプログレスバーの生成と配置で、次にfor文を回すリストを用意します。

  • この際にプログレスバーの最大値設定はmaximum=1として以降の設定は割合計算としました。

  • そのため、for文の最後にprogbar.configure(value=(i+1)/len(prog_list))progbar.update()を入れればプログレスバーが進んでいきます。

  • ネット上で確認できるコードだとafter関数を使っていたり、variableで指定した変数を変更している例が多いようなのですが、for文中に入れるとうまく動きませんでした。

  • プログレスバーはfor文で回している数の分だけ進めるのであれば、これが一番シンプルな気がします。

作例(ソースコード)

  • enumerateでfor文を回せばリストの要素も利用できますし、実際のプログラムではわかりやすいかなと思います。

  • 以下のコードでは2重ループを2本のプログレスバーで表示させています。

animation.gif

import time
import tkinter as tk
from tkinter import ttk

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master.geometry('420x160')
        self.master.title('sample')
        self.master.grid_rowconfigure((0, 1, 2), weight=1)
        self.master.grid_columnconfigure((0, 1), weight=1)

        self.label_1 = ttk.Label(self.master, text='')
        self.label_2 = ttk.Label(self.master, text='')
        self.progbar1 = ttk.Progressbar(self.master, length=400, mode="determinate", maximum=1)
        self.progbar2 = ttk.Progressbar(self.master, length=400, mode="determinate", maximum=1)
        self.button1 = ttk.Button(self.master, text='実行', width=20, command=self.loop_function)
        self.button2 = ttk.Button(self.master, text='リセット', width=20, command=self.reset_bar)
        self.label_1.grid(row=0, column=0, padx=10, pady=10)
        self.label_2.grid(row=0, column=1, padx=10, pady=10)
        self.progbar1.grid(row=1, column=0, columnspan=2, padx=10, pady=(0, 5))
        self.progbar2.grid(row=2, column=0, columnspan=2, padx=10, pady=(0, 10))
        self.button1.grid(row=3, column=0, padx=10, pady=(0, 10))
        self.button2.grid(row=3, column=1, padx=10, pady=(0, 20))

        # ループ処理をまわすリスト
        self.prog_list1 = list('abcdefghijklmnopqrstuvwxyz')
        self.prog_list2 = list('あいうえお')

    # ループ処理
    def loop_function(self):
        # ループ処理
        for i, item2 in enumerate(self.prog_list2):
            for j, item1 in enumerate(self.prog_list1):
                time.sleep(0.15)
                # ラベル表示変更
                self.label_1.configure(text=f'{item2}-{item1}')
                self.label_2.configure(text=f'{j+1}/{len(self.prog_list1)}')
                # プログレスバー表示変更
                self.progbar1.configure(value=(j+1)/len(self.prog_list1))
                self.progbar1.update()
            # プログレスバー表示変更
            self.progbar2.configure(value=(i+1)/len(self.prog_list2))
            self.progbar2.update()

    # リセット処理
    def reset_bar(self):
        # ラベル表示リセット
        self.label_1.configure(text='')
        self.label_2.configure(text='')
        # プログレスバー表示リセット
        self.progbar1.configure(value=0)
        self.progbar1.update()
        self.progbar2.configure(value=0)
        self.progbar2.update()


if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6