GUI

[Python Tkinter] 別ウィンドウにプログレスバーを表示する方法

PythonのTkinterを使用して別ウィンドウにプログレスバーを表示するには、Toplevelウィンドウを作成し、その中にttk.Progressbarウィジェットを配置します。

Toplevelはメインウィンドウとは別のウィンドウを作成するために使用され、ttk.Progressbarは進行状況を視覚的に示すためのウィジェットです。

プログレスバーの更新は、start()step()メソッドを使って行います。

別ウィンドウにプログレスバーを表示する手順

Toplevelウィンドウの作成

Toplevelウィンドウは、メインウィンドウとは別に表示されるウィンドウです。

これを使ってプログレスバーを表示するためのウィンドウを作成します。

以下のサンプルコードでは、メインウィンドウからToplevelウィンドウを開く方法を示しています。

import tkinter as tk
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックすると別ウィンドウが開く。

ttk.Progressbarの配置

ttk.Progressbarは、Tkinterのテーマ付きウィジェットで、プログレスバーを簡単に作成できます。

Toplevelウィンドウにプログレスバーを配置する方法を以下に示します。

import tkinter as tk
from tkinter import ttk
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()

プログレスバーの初期設定

プログレスバーの初期設定を行うことで、表示する進行状況の範囲や初期値を設定できます。

以下のコードでは、プログレスバーの最大値を100に設定し、初期値を0にしています。

import tkinter as tk
from tkinter import ttk
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100  # 最大値を100に設定
    progress_bar['value'] = 0       # 初期値を0に設定
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックすると最大値100のプログレスバーがある別ウィンドウが開く。

プログレスバーの動作を制御する方法

プログレスバーの動作を制御するためには、進行状況を更新する関数を作成し、ボタンなどのイベントにバインドします。

以下のコードでは、ボタンをクリックすることでプログレスバーが進行します。

import tkinter as tk
from tkinter import ttk
def update_progress(progress_bar):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()  # プログレスバーを更新
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
    start_button = tk.Button(progress_window, text="開始", command=lambda: update_progress(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()

メインウィンドウと別ウィンドウの連携

メインウィンドウと別ウィンドウの連携を行うことで、ユーザーの操作に応じてプログレスバーの状態を変更できます。

以下のコードでは、メインウィンドウのボタンをクリックすることで、プログレスバーの進行状況を更新します。

import tkinter as tk
from tkinter import ttk
def update_progress(progress_bar):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()
def open_progress_window():
    global progress_bar  # グローバル変数として宣言
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
def start_progress():
    update_progress(progress_bar)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
start_button = tk.Button(root, text="進行開始", command=start_progress)
start_button.pack(pady=10)
root.mainloop()

プログレスバーの動作をカスタマイズする

プログレスバーの進行速度を調整する

プログレスバーの進行速度を調整するためには、進行状況を更新する間隔を設定します。

time.sleep()を使用して、更新の間に待機時間を設けることで、進行速度を調整できます。

以下のコードでは、進行速度を遅くするために0.1秒の待機時間を設けています。

import tkinter as tk
from tkinter import ttk
import time
def update_progress(progress_bar):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()
        time.sleep(0.1)  # 進行速度を調整
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
    start_button = tk.Button(progress_window, text="開始", command=lambda: update_progress(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()

プログレスバーの停止とリセット

プログレスバーを停止させたり、リセットしたりするためには、ボタンを追加してその機能を実装します。

以下のコードでは、停止ボタンとリセットボタンを追加し、それぞれの機能を実装しています。

import tkinter as tk
from tkinter import ttk
import time
def update_progress(progress_bar):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()
        time.sleep(0.1)
def stop_progress(progress_bar):
    progress_bar['value'] = 0  # プログレスバーをリセット
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
    start_button = tk.Button(progress_window, text="開始", command=lambda: update_progress(progress_bar))
    start_button.pack(pady=10)
    stop_button = tk.Button(progress_window, text="停止", command=lambda: stop_progress(progress_bar))
    stop_button.pack(pady=5)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、開始ボタンを押すとプログレスバーが進行し、停止ボタンでリセットできる。

プログレスバーの進行状況を手動で更新する

プログレスバーの進行状況を手動で更新するためには、ユーザーが入力した値に基づいてプログレスバーを更新する機能を追加します。

以下のコードでは、エントリーボックスを使って手動で進行状況を設定できるようにしています。

import tkinter as tk
from tkinter import ttk
def update_progress(progress_bar, value):
    progress_bar['value'] = value
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
    entry = tk.Entry(progress_window)
    entry.pack(pady=5)
    update_button = tk.Button(progress_window, text="更新", command=lambda: update_progress(progress_bar, int(entry.get())))
    update_button.pack(pady=5)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、エントリーボックスに数値を入力して更新ボタンを押すとプログレスバーがその値に更新される。

プログレスバーの進行状況をリアルタイムで表示する

プログレスバーの進行状況をリアルタイムで表示するためには、別スレッドを使用してバックグラウンドで処理を行い、プログレスバーを更新します。

以下のコードでは、threadingモジュールを使ってリアルタイムで進行状況を表示しています。

import tkinter as tk
from tkinter import ttk
import time
import threading
def update_progress(progress_bar):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()
        time.sleep(0.1)
def start_progress(progress_bar):
    thread = threading.Thread(target=update_progress, args=(progress_bar,))
    thread.start()
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    progress_bar['maximum'] = 100
    progress_bar['value'] = 0
    start_button = tk.Button(progress_window, text="開始", command=lambda: start_progress(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、開始ボタンを押すとプログレスバーがリアルタイムで進行する。

別ウィンドウの閉じ方とイベント処理

別ウィンドウを閉じる方法

別ウィンドウを閉じるには、Toplevelウィンドウのdestroy()メソッドを使用します。

このメソッドを呼び出すことで、ウィンドウを閉じることができます。

以下のコードでは、別ウィンドウに閉じるボタンを追加し、そのボタンをクリックすることでウィンドウを閉じる方法を示しています。

import tkinter as tk
from tkinter import ttk
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    close_button = tk.Button(progress_window, text="閉じる", command=progress_window.destroy)
    close_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、閉じるボタンを押すとそのウィンドウが閉じる。

別ウィンドウの閉じるイベントを処理する

別ウィンドウが閉じられる際に特定の処理を行いたい場合、ウィンドウのprotocolメソッドを使用して、閉じるイベントを処理できます。

以下のコードでは、ウィンドウが閉じられる際にメッセージを表示する処理を追加しています。

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
def on_closing(progress_window):
    if messagebox.askokcancel("確認", "ウィンドウを閉じますか?"):
        progress_window.destroy()
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    progress_window.protocol("WM_DELETE_WINDOW", lambda: on_closing(progress_window))
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、ウィンドウを閉じる際に確認メッセージが表示される。

プログレスバーの終了処理

プログレスバーの処理が完了した際に、ウィンドウを自動的に閉じることもできます。

プログレスバーが100%に達したときに、ウィンドウを閉じる処理を追加します。

以下のコードでは、プログレスバーが完了した際にウィンドウを閉じるようにしています。

import tkinter as tk
from tkinter import ttk
import time
def update_progress(progress_bar, progress_window):
    for i in range(101):
        progress_bar['value'] = i
        progress_bar.update_idletasks()
        time.sleep(0.1)
    progress_window.destroy()  # プログレスバーが完了したらウィンドウを閉じる
def open_progress_window():
    progress_window = tk.Toplevel()
    progress_window.title("プログレスバーウィンドウ")
    progress_window.geometry("300x100")
    progress_bar = ttk.Progressbar(progress_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    
    start_button = tk.Button(progress_window, text="開始", command=lambda: update_progress(progress_bar, progress_window))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="プログレスバーを開く", command=open_progress_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ボタンをクリックするとプログレスバーがある別ウィンドウが開き、開始ボタンを押すとプログレスバーが進行し、完了後にウィンドウが自動的に閉じる。

応用例:プログレスバーを使った実用的なアプリケーション

ファイルのダウンロード進行状況を表示する

ファイルのダウンロード進行状況を表示するためには、HTTPリクエストを使用してファイルをダウンロードし、その進行状況をプログレスバーで表示します。

以下のコードでは、requestsライブラリを使用してファイルをダウンロードし、進行状況を更新しています。

import tkinter as tk
from tkinter import ttk
import requests
def download_file(url, progress_bar):
    response = requests.get(url, stream=True)
    total_size = int(response.headers.get('content-length', 0))
    downloaded_size = 0
    for data in response.iter_content(chunk_size=1024):
        downloaded_size += len(data)
        progress_bar['value'] = (downloaded_size / total_size) * 100
        progress_bar.update_idletasks()
def open_download_window():
    download_window = tk.Toplevel()
    download_window.title("ファイルダウンロード")
    download_window.geometry("300x100")
    progress_bar = ttk.Progressbar(download_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    url = "https://example.com/samplefile.zip"  # ダウンロードするファイルのURL
    download_file(url, progress_bar)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="ダウンロード開始", command=open_download_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、ダウンロード開始ボタンをクリックするとファイルのダウンロード進行状況がプログレスバーで表示される。

バッチ処理の進行状況を表示する

バッチ処理の進行状況を表示するためには、複数のタスクを順次実行し、その進行状況をプログレスバーで示します。

以下のコードでは、擬似的なバッチ処理を行い、進行状況を更新しています。

import tkinter as tk
from tkinter import ttk
import time
def batch_process(progress_bar):
    total_tasks = 10
    for i in range(total_tasks):
        time.sleep(1)  # 各タスクの処理を模擬
        progress_bar['value'] = (i + 1) / total_tasks * 100
        progress_bar.update_idletasks()
def open_batch_window():
    batch_window = tk.Toplevel()
    batch_window.title("バッチ処理")
    batch_window.geometry("300x100")
    progress_bar = ttk.Progressbar(batch_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    start_button = tk.Button(batch_window, text="処理開始", command=lambda: batch_process(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="バッチ処理開始", command=open_batch_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、バッチ処理開始ボタンをクリックするとバッチ処理の進行状況がプログレスバーで表示される。

データベースのクエリ実行中にプログレスバーを表示する

データベースのクエリを実行中にプログレスバーを表示することで、ユーザーに処理の進行状況を示すことができます。

以下のコードでは、擬似的なデータベースクエリを実行し、その進行状況をプログレスバーで表示しています。

import tkinter as tk
from tkinter import ttk
import time
def execute_query(progress_bar):
    total_steps = 5
    for i in range(total_steps):
        time.sleep(1)  # クエリ実行を模擬
        progress_bar['value'] = (i + 1) / total_steps * 100
        progress_bar.update_idletasks()
def open_query_window():
    query_window = tk.Toplevel()
    query_window.title("データベースクエリ")
    query_window.geometry("300x100")
    progress_bar = ttk.Progressbar(query_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    start_button = tk.Button(query_window, text="クエリ実行", command=lambda: execute_query(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="クエリ実行開始", command=open_query_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、クエリ実行開始ボタンをクリックするとデータベースクエリの進行状況がプログレスバーで表示される。

長時間の計算処理にプログレスバーを使用する

長時間の計算処理を行う際にプログレスバーを使用することで、ユーザーに処理の進行状況を示すことができます。

以下のコードでは、擬似的な計算処理を行い、その進行状況をプログレスバーで表示しています。

import tkinter as tk
from tkinter import ttk
import time
def long_calculation(progress_bar):
    total_steps = 20
    for i in range(total_steps):
        time.sleep(0.5)  # 計算処理を模擬
        progress_bar['value'] = (i + 1) / total_steps * 100
        progress_bar.update_idletasks()
def open_calculation_window():
    calculation_window = tk.Toplevel()
    calculation_window.title("計算処理")
    calculation_window.geometry("300x100")
    progress_bar = ttk.Progressbar(calculation_window, mode='determinate')
    progress_bar.pack(pady=20, padx=20, fill=tk.X)
    start_button = tk.Button(calculation_window, text="計算開始", command=lambda: long_calculation(progress_bar))
    start_button.pack(pady=10)
root = tk.Tk()
root.title("メインウィンドウ")
root.geometry("300x100")
open_button = tk.Button(root, text="計算処理開始", command=open_calculation_window)
open_button.pack(pady=20)
root.mainloop()
メインウィンドウが表示され、計算処理開始ボタンをクリックすると長時間の計算処理の進行状況がプログレスバーで表示される。

まとめ

この記事では、PythonのTkinterを使用して別ウィンドウにプログレスバーを表示する方法について詳しく解説しました。

プログレスバーの基本的な使い方から、ファイルのダウンロードやバッチ処理、データベースのクエリ実行中の進行状況表示、さらには長時間の計算処理における応用例まで、幅広く取り上げました。

これらの知識を活用することで、ユーザーにとって使いやすいインターフェースを持つアプリケーションを作成することが可能です。

ぜひ、実際のプロジェクトに取り入れて、プログレスバーを活用したアプリケーションを作成してみてください。

関連記事

Back to top button