【Python】Tkinter画面遷移-複数ウィンドウをクラス化

当サイトで紹介する商品・サービス等の外部リンクは、アフィリエイト広告を含む場合があります。
スポンサーリンク
本記事を読むと以下の実行ができます

数値を入れて開始をするとウィンドウを切り替えてカウントダウンをする

TkinterはPythonを使って、デスクトップアプリケーションを作ることができるライブラリです。

Tkinterの1つのウィンドウを使ってソフトを動かすことが可能ですが、
画面遷移を用いて、複数のウィンドウを表示する方が利便性が良いことがあります。

例えば、ログインフォームを作るとき画面を2つにして、
ログイン情報を入力、認証ができたら画面遷移で個人ページに進む。

このように画面の切り替えは、ユーザーが使いやすいGUIの作成につながります。

本記事では、複数のウィンドウを扱う方法(画面遷移)について紹介します。

本記事は次の人におすすめ
  • Pythonでデスクトップアプリケーションを作れるようになりたい
  • Tkinterの画面切り替え(画面遷移)で複数ウィンドウを操作したい
  • 画面遷移のクラス化をしたい
スポンサーリンク

Tkinter画面切り替え

Tkinterの画面切り替えするには、pack_forget()メソッドを使用します。
稼働させるウィンドウの数だけ関数を作り、この関数を表示・非表示を入れ替えて行います。

以下に、簡単なコードを紹介します。

import tkinter as tk

def show_screen_a():
    screen_a.pack()
    screen_b.pack_forget()

def show_screen_b():
    screen_a.pack_forget()
    screen_b.pack()

root = tk.Tk()
root.title("画面切り替え")
root.geometry("250x50")

# スクリーンAのフレーム
screen_a = tk.Frame(root)
screen_a.pack()

label_a = tk.Label(screen_a, text="ScreenA")
label_a.pack()

button_a = tk.Button(screen_a, text="To B", command=show_screen_b)
button_a.pack()

# スクリーンBのフレーム
screen_b = tk.Frame(root)
screen_b.pack()

label_b = tk.Label(screen_b, text="ScreenB")
label_b.pack()

button_b = tk.Button(screen_b, text="To A", command=show_screen_a)
button_b.pack()

# 最初はスクリーンAを表示
show_screen_a()

root.mainloop()

show_screen_a()とshow_screen_b()関数を使用して、
スクリーンAとスクリーンBの表示を切り替えています。

ラベル表示が変わっていますが、文字を変えているのではなく、
ボタンをクリックすることで画面が遷移しています。

Tkinterのラベル表示についてまとめています。

ボタンのcommandパラメータにそれぞれの関数を指定し、
ボタンが押されて関数show_screen_a()の時はスクリーンBに関するものは非表示、
show_screen_b()の時はスクリーンAに関するものは非表示としています。

Tkinterのボタン表示とボタンとdef関数を連携についてまとめています。

クラス化した場合の画面遷移

Tkinterにおけるクラス化とは、PythonのGUIライブラリであるTkinterをオブジェクト指向プログラミングの方法で使うために、
Tkinterのウィジェットやイベント処理をクラスとして定義することを指します。

Tkinterをクラス化する場合、tk.Tkを継承したクラスを作成し、
そのクラス内でウィジェットやイベント処理を定義します。

クラス化のメリット
  • 可読性の向上: GUI要素やイベント処理が分かりやすく整理される。
  • 再利用性の向上: 同じクラスを他のプロジェクトや異なるウィンドウのテンプレートとして使える。
  • メンテナンスがしやすい: 複雑なアプリケーションでもコードが整理され、修正や機能追加が容易になる。
import tkinter as tk

class ChangeScreen(tk.Tk):
    def show_screen_a(self):
        self.screen_a.pack()
        self.screen_b.pack_forget()

    def show_screen_b(self):
        self.screen_a.pack_forget()
        self.screen_b.pack()
        
    def __init__(self):
        super().__init__()
        self.title("画面切り替え")
        self.geometry("250x50")


        # スクリーンAのフレーム
        self.screen_a = tk.Frame(self)
        self.screen_a.pack()

        self.label_a = tk.Label(self.screen_a, text="ScreenA")
        self.label_a.pack()

        self.button_a = tk.Button(self.screen_a, text="To B", command=self.show_screen_b)
        self.button_a.pack()

        # スクリーンBのフレーム
        self.screen_b = tk.Frame(self)
        self.screen_b.pack()

        self.label_b = tk.Label(self.screen_b, text="ScreenB")
        self.label_b.pack()

        self.button_b = tk.Button(self.screen_b, text="To A", command=self.show_screen_a)
        self.button_b.pack()

        # 最初はスクリーンAを表示
        self.show_screen_a()

if __name__ == "__main__":
    app = ChangeScreen()
    app.mainloop()

このコードでは、ChangeScreenクラスがアプリケーションのメインクラスになります。
Pythonで関数を登録する際は、def関数を使いますが、多用してしまうとコードが読みづらくなります。
def関数の代わりに、Classで一つにまとめれば、コードが見やすくなります。

クラス化すると、「if name==”main”:」というコードを使うようになります。
消去してもプログラムは正常に処理されますが、classを使う場合は入れておくべきです。

そもそも、「if name==”main”:」は、他のスクリプトからインポートされた場合、if文以下が実行されないようにします。

例えば、あるスクリプトがモジュールとして他のスクリプトでインポートした場合、そのスクリプトだけで有効な初期化処理や関数定義があると、これらが不用意に実行されてしまいます。

この問題を避けるためにも処理をクラス化した場合は、「if name==”main”:」を使用しましょう。

画面遷移型カウントダウンタイマー

画面切り替え(画面遷移)は、ユーザーからテキストボックスで入力されて、
ボタンを押すことで、画面が切り替わるというプログラムが多いです。

本記事ではユーザーに数値を入力してボタンが押されると、
その値を取得し、画面遷移をして、カウントを進めるタイマーを作成します。
また、タイマーが終了した際はウィンドウが通知を流します。

一定時間処理を止めるsleep関数(timeモジュール)を使うことでもカウントダウンタイマーは作成可能です。

ソースコード

import tkinter as tk
from tkinter import messagebox

# メインウィンドウを作成する
root = tk.Tk()
root.title("カウントダウンタイマー")

#ウィンドウのサイズ
root.geometry("300x150")

def start_countdown():
    global time_remaining

    # 入力した時間を取得
    input_time = int(entry.get())

    if input_time > 0:
        # 入力した時間を設定
        time_remaining = input_time +1

        # 入力画面を非表示にし、カウントダウン画面を表示する
        entry.pack_forget()
        start_button.pack_forget()
        label.pack(padx=20, pady=40)

        # カウントダウンを開始する
        countdown()
    else:
        messagebox.showerror("エラー", "正の数を入力してください。")

def countdown():
    global time_remaining

    # 残り時間を1秒減らす
    time_remaining -= 1

    # ラベルのテキストを更新する
    label.config(text=str(time_remaining))

    if time_remaining > 0:
        # 1秒後に再びcountdown関数を呼び出す
        root.after(1000, countdown)
    else:
        # カウントダウンが0になったらメッセージボックスを表示する
        messagebox.showinfo("終了", "カウントダウンが終了しました!")
        # ラベルを非表示にし、再度入力画面を表示する
        label.pack_forget()
        entry.pack()
        start_button.pack()

# 入力欄を作成する
entry = tk.Entry(root, font=("Helvetica", 24))
entry.pack(padx=20, pady=20)

# カウントダウンを開始するボタンを作成する
start_button = tk.Button(root, text="開始", command=start_countdown)
start_button.pack(side="bottom")

# 残り時間を表示するためのラベルを作成する
label = tk.Label(root, font=("Helvetica", 48))

# Tkinterのイベントループを開始する
root.mainloop()

Pythonの学習進め方

Pythonでできることは多岐に渡ります。

Pythonでできること
  • 機械学習・人工知能
  • データ解析・統計分析
  • ファイル操作・システム管理
  • GUIアプリ開発

Pythonは強力で柔軟なプログラミング言語ですが、常に情報がアップデートされるので、
新しいライブラリやフレームワークを独学で学び続けることは困難です。

Udemyは動画で目的に応じた講座を受講できるのでレベルを合わせて学習できます。
購入した講座は再生・停止・スキップなどが可能なオンデマンド形式なので、
専門的な内容を自分のペースで独学できます。

Udemyの特徴
  • プロのエンジニアによる講習が受けられる
  • 自分のペースで学習を進められる
  • オンデマンド形式だから何度でも視聴可能
  • 不満足なコースは視聴していても返金可能返金ポリシー

Pythonでデータサイエンスや人工知能、GUIを学びたい人はUdemy学習を取り入れましょう。
数多くある講座の中から特におすすめな講座を5つ紹介します。

ビックセール開催中(10月11日まで)
対象のコースが1500円から(最大95%OFF)

多彩な講座から自分に合った講座を探そう!

最大94%OFF

終了まで

時間

Pythonをインストールから環境設定、基本文法が学習できる。さらに、モジュールの使い方やファイル操作の他に暗号化、並列化、インフラ自動化、キューイングシステム、非同期処理についても学べます。

Pythonの基礎を押さえつつ、人口知能やニューラルネットワーク、機械学習を取り扱う。機械学習ライブラリで文字認識や株価分析などを行う。

データサイエンティストになるために必要なツールについて学ぶことができる。統計分析、NumpyやPandasなどを使ったPythonのプログラミング、機械学習の実装、ディープラーニングの実装を学習できる。

PythonでGUIを作成する方法を取り扱う。Tkinterの発展的な操作まで学習できる。翻訳アプリ、家計簿アプリ、電卓アプリ、音楽再生アプリなど作成して、exeファイル化する。

解説

はじめに、ライブラリとモジュールをインポートします。
messageboxモジュールは、メッセージボックスを表示、関数をします。
カウントが終了したときと0を含めた、負の数字を入力したときユーザーに知らせます。

参考ページ:「tkinter.messagebox — Tkinterのメッセージプロンプト

import tkinter as tk
from tkinter import messagebox

つづいて、tk.Tk()を呼び出して、メインウィンドウを作成します。
title()メソッドでウィンドウのタイトルを設定します。
geometry()メソッドでウィンドウのサイズを設定します。

# メインウィンドウを作成する
root = tk.Tk()
root.title("カウントダウンタイマー")

#ウィンドウのサイズ
root.geometry("300x150")

start_countdown()関数は、カウントダウンを開始するために呼び出されます。
入力した時間を取得し、時間が正の数であるかどうかを確認します。正の数であれば、カウントダウン画面を表示し、countdown()関数を呼び出してカウントダウンを開始します。
時間が0以下(負の値)の場合はエラーメッセージを表示します。

複数の関数で変数を共有するときはグローバル変数を使います。必要に応じて変数を変更や参照が可能です。ただし、ローカル変数とは異なり、グローバル関数はプログラムの可読性や保守性に影響を与える可能性があるため、注意が必要です。

def start_countdown():
    global time_remaining

    # 入力した時間を取得
    input_time = int(entry.get())

    if input_time > 0:
        # 入力した時間を設定
        time_remaining = input_time +1

        # 入力画面を非表示にし、カウントダウン画面を表示する
        entry.pack_forget()
        start_button.pack_forget()
        label.pack(padx=20, pady=40)

        # カウントダウンを開始する
        countdown()
    else:
        messagebox.showerror("エラー", "正の数を入力してください。")

countdown()関数は、カウントダウンを実行するために呼び出されます。残り時間を1秒減らし、config()メソッドを使用して「time_remaining」の数値をラベルのテキストを更新します。
ただし、str()関数を使っているので、数字ではなく文字列の変数です。

時間が0より大きい場合は、1秒後に再びcountdown()関数を呼び出します。時間が0になった場合は、終了メッセージを表示し、入力画面を再表示します。

def countdown():
    global time_remaining

    # 残り時間を1秒減らす
    time_remaining -= 1

    # ラベルのテキストを更新する
    label.config(text=str(time_remaining))

    if time_remaining > 0:
        # 1秒後に再びcountdown関数を呼び出す
        root.after(1000, countdown)
    else:
        # カウントダウンが0になったらメッセージボックスを表示する
        messagebox.showinfo("終了", "カウントダウンが終了しました!")
        # ラベルを非表示にし、再度入力画面を表示する
        label.pack_forget()
        entry.pack()
        start_button.pack()

tk.Entry()を呼び出して、入力欄を作成します。fontパラメータでフォントの設定を行い、pack()メソッドでウィンドウに配置します。

# 入力欄を作成する
entry = tk.Entry(root, font=24)
entry.pack(padx=20, pady=20)

tk.Button()を呼び出して、カウントダウンを開始するボタンを作成します。
ボタンのテキストは「開始」に設定し、commandパラメータにはカウントダウンを開始するためにstart_countdown()関数を指定します。
pack()メソッドを使用してボタンをウィンドウの底部に配置します。

# カウントダウンを開始するボタンを作成する
start_button = tk.Button(root, text="開始", command=start_countdown)
start_button.pack(side="bottom")

tk.Label()を呼び出して、残り時間を表示するためのラベルを作成します。fontパラメータでフォントの設定を行います。

# 残り時間を表示するためのラベルを作成する
label = tk.Label(root, font=48)

最後に、mainloop()メソッドを呼び出して、Tkinterのイベントループを開始します。これにより、ウィンドウが表示され、ユーザーの入力やボタンのクリックなどのイベントが処理されます。

# Tkinterのイベントループを開始する
root.mainloop()

まとめ

今回は、Tkinterの画面切り替えて複数ウィンドウを扱う方法を紹介しました。

Tkinterの画面切り替え(画面遷移)は、pack_forget()メソッドを使用します。
稼働させるウィンドウの数だけの関数を扱い、この関数を表示、非表示を入れ替えて行います。

A、Bの画面において、Aが表示されるとBに関するラベルやボタンは非表示。Bが表示されると、Aに関するラベルやボタンは非表示。という処理が行われます。

この記事を書いた人

プロフィール

アリッシア

                 

大学4年間で何か胸を張れるスキルを身に着けたくて当サイト運営を始めました。
現在、大学院に進学するか就職するか迷いながら勉強しています。
詳しいプロフィールはこちら

Contact icon

contact

X icon

X

Instagram icon

Instagram

Note icon

Note

スポンサーリンク
Python
フォローする
タイトルとURLをコピーしました