Tkinterのこのチュートリアルシリーズでは、TkinterのSpinboxとProgressbarウィジェットについて学びます。
続けて、アプリケーションに追加できるウィジェットをさらに調べていきます。
それでは、例題を使って一つずつ見ていきましょう。
Tkinter Spinbox Widgetを使う
TkinterのSpinboxウィジェットは、固定された値の集合から選択することができるウィジェットです。
TkinterのEntryウィジェットを覚えていますか?エンドユーザが限られた選択肢の中からしか選べないように制限したいとします、ここではあまり役に立ちません!
むしろ、固定された選択肢の中から選びたいはずです。
では、その使い方を見てみましょう。
これは Entry ウィジェットとほぼ同じですが、オプションの引数 values で値のリストを指定します。
これはタプルです。
spin_box = tk.Spinbox(master, values)
|
値が整数値などの場合は、 from_ と to という引数を使用して、値の範囲から指定することもできます。
注意: キーワード引数 from_ の末尾にはアンダースコアが付きますが、これは from が Python の予約キーワードであるためです。
spin_box = tk.Spinbox(master, from_, to)
|
それでは、いくつかの定義済みオプションを持つスピンボックスウィジェットを持つ、シンプルなアプリケーションを作ってみましょう。
ウィジェットを適切な位置に配置するために、グリッドジオメトリマネージャを使用します。
また、各ウィジェットにラベルを付けて、他の人がテキストで識別できるようにします。
import tkinter as tk
# Create the master objectmaster = tk.Tk()
# Create a spinbox widgetspinbox_1 = tk.Spinbox(master, values=("Python", "Java", "C++"))
# And a label for itlabel_1 = tk.Label(master, text="Language")
# Create another spinbox widgetspinbox_2 = tk.Spinbox(master, from_=1, to=3)
# And a label for itlabel_2 = tk.Label(master, text="Value")
# Use the grid geometry manager to put the widgets in the respective positionlabel_1.grid(row=0, column=0)
spinbox_1.grid(row=0, column=1)
label_2.grid(row=1, column=0)
spinbox_2.grid(row=1, column=1)
# The application mainlooptk.mainloop() |
結果は以下の通りです。
import tkinter as tk
# Necessary for the Progressbar widgetimport tkinter.ttk as ttk
|
progress_bar = ttk.Progressbar(orient, mode, maximum, value)
|
これを自分で実行すると、スピンボックスウィジェットの両方について、上で提供した特定のリストから値を調整できることがわかります。
このウィジェットの詳細な引数や調整方法については、公式ドキュメントを参照してください。
それでは、ProgressBarウィジェットを見てみましょう。
プログレスバーウィジェットの使い方
Progressbarウィジェットは、長時間実行される操作の状態を表示します。
例えば、何かの処理にどれくらいの時間がかかっているかを視覚化したい場合、Progressbar を使えばそれが可能です!
これは tkinter.ttk モジュールで利用可能なので、別途インポートする必要があります。
progress_bar.start(interval=None)
|
ここでは、簡単なオプションを使って、その使い方を見ていきます。
全リストはこちらで見ることができます。
progress_bat.step(amount=10)
|
ここで、orientはプログレスバーの向きを指定します。
これは “horizontal” か “vertical” のどちらかです。
このウィジェットは2つのモードで動作することができます。
- 決定版” -> 作業の総量に対する完了量を表示します。
- 不確定」-> 作業が進行していることを示すために、単にアニメーションを表示します。
プログレスバーは、バーの現在の 値 が 最大値 に達するまで続きます。
プログレスバーの値のインクリメントを開始するには、 progress_bar.start(interval) を使用する必要があります。
これは、 interval ミリ秒ごとに自動的にこれを行います。
ここでは None とし、デフォルト値である 50 ミリ秒に設定します。
import tkinter as tk
import tkinter.ttk as ttk
# Create the master objectmaster = tk.Tk()
# Create a progressbar widgetprogress_bar = ttk.Progressbar(master, orient="horizontal",
mode="determinate", maximum=100, value=0)
# And a label for itlabel_1 = tk.Label(master, text="Progress Bar")
# Use the grid managerlabel_1.grid(row=0, column=0)
progress_bar.grid(row=0, column=1)
# Start auto-incrementing periodicallyprogress_bar.start()progress_bar.step(10)
# The application mainlooptk.mainloop() |
次に、step() メソッドを使用して、値が amount = 10 ずつ増加することを確認します。
progress_bar['value'] = 0
master.update() |
今までのコード一式を載せておきます。
import tkinter as tk
import tkinter.ttk as ttk
import time
# Create the master objectmaster = tk.Tk()
# Create a progressbar widgetprogress_bar = ttk.Progressbar(master, orient="horizontal",
mode="determinate", maximum=100, value=0)
# And a label for itlabel_1 = tk.Label(master, text="Progress Bar")
# Use the grid managerlabel_1.grid(row=0, column=0)
progress_bar.grid(row=0, column=1)
# Necessary, as the master object needs to draw the progressbar widget# Otherwise, it will not be visible on the screenmaster.update()progress_bar['value'] = 0
master.update()while progress_bar['value'] < 100:
progress_bar['value'] += 10
# Keep updating the master object to redraw the progress bar
master.update()
time.sleep(0.5)
# The application mainlooptk.mainloop() |
結果は以下の通りです。

動くプログレスバーが表示される。
これは value を 0 から 100 まで、50 ミリ秒ごとに 10 単位で増加させる。
しかし、私たちは正しいアプローチをしているのだろうか?
しかし、ここでの問題は、プログレスバーが maximum に達した後、再び 0 にリセットされることです。
これを避けるために、プログレスバーを stop() する必要があります。
しかし、これは思ったより多くの問題を引き起こすことに気づきました。
というのも、その場合、更新中のプログレスバーを得ることができないからです。
最大の問題は、私たちのメインアプリケーションが tk.mainloop() 関数の中で実行されることです。
そのため、リアルタイムで実行するためには、これらすべてを事前に計算する必要があります。
そこで、いくつかググってみたところ、start() と stop() を使うのは正しい方法ではないことがわかりました。
なぜなら、プログレスバーがどのように再描画されるかについては何も書かれていないからです。
したがって、(悲しいかな)残された唯一の解決策は、プログレスバーの value を自分自身で手動で更新することです。
StackOverflowに投稿された内容を見ると、他のTkinterプログラマは確かにそのような結論に達しているようです。
この記事もチェック:TkinterのScaleウィジェットの使い方を解説する
ウィジェットの値を自分で修正する
そのために、すべてのTkinterウィジェットは辞書属性を持っており、それを変更することができます! そうです、とても簡単です。
プログレスバーの値を更新するには、次のようにします。

ただし、masterオブジェクトに、このウィジェットが新しい値で更新されたことを master.update() で通知する必要があります。
では、これらの変更を考慮して、古いコードと間違ったコードを書き直します。

これで、ウィジェットの値を更新するという大変な作業をすべて自分たちで行う一方で、より多くの制御ができるようになりました。
このコードでは、プログレスバーの連続したシーケンスを表示し、valueが100に達したときに停止することができるはずです。
このプログラムが動作することを示す簡単な GIF を以下に示します。

この記事もチェック:Tkinterのテキストウィジェットとスクロールバーの使い方を解説する
まとめ
最後に、TkinterのSpinboxとProgressbarウィジェットを使用するためのチュートリアルを終了します。
Tkinterのコンテンツはまだまだ続きますので、お楽しみに。
この記事もチェック:Tkinter GUI ウィジェット – 完全なリファレンス