数値を入れて開始をするとウィンドウを切り替えてカウントダウンをする
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の表示を切り替えています。
ラベル表示が変わっていますが、文字を変えているのではなく、
ボタンをクリックすることで画面が遷移しています。
ボタンのcommandパラメータにそれぞれの関数を指定し、
ボタンが押されて関数show_screen_a()の時はスクリーンBに関するものは非表示、
show_screen_b()の時はスクリーンAに関するものは非表示としています。
クラス化した場合の画面遷移
Tkinterにおけるクラス化とは、PythonのGUIライブラリであるTkinterをオブジェクト指向プログラミングの方法で使うために、
Tkinterのウィジェットやイベント処理をクラスとして定義することを指します。
Tkinterをクラス化する場合、tk.Tkを継承したクラスを作成し、
そのクラス内でウィジェットやイベント処理を定義します。
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”:」を使用しましょう。
画面遷移型カウントダウンタイマー
画面切り替え(画面遷移)は、ユーザーからテキストボックスで入力されて、
ボタンを押すことで、画面が切り替わるというプログラムが多いです。
本記事ではユーザーに数値を入力してボタンが押されると、
その値を取得し、画面遷移をして、カウントを進めるタイマーを作成します。
また、タイマーが終了した際はウィンドウが通知を流します。
ソースコード
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は強力で柔軟なプログラミング言語ですが、常に情報がアップデートされるので、
新しいライブラリやフレームワークを独学で学び続けることは困難です。
Udemyは動画で目的に応じた講座を受講できるのでレベルを合わせて学習できます。
購入した講座は再生・停止・スキップなどが可能なオンデマンド形式なので、
専門的な内容を自分のペースで独学できます。
Pythonでデータサイエンスや人工知能、GUIを学びたい人はUdemy学習を取り入れましょう。
数多くある講座の中から特におすすめな講座を5つ紹介します。
ビックセール開催中(10月11日まで)
対象のコースが1500円から(最大95%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に関するラベルやボタンは非表示。という処理が行われます。