【Tkinter】複数の画面(フレーム)をボタン操作で切り替えて表示させる【画面遷移(tkraise)】
2020.12.06 /
私は社内で使用するためのデスクトップアプリケーションをよく開発しています。
社内業務の効率化には、その業務に合ったデスクトップアプリケーションを開発するのが簡単ですからね。
デスクトップアプリケーションの使い勝手をよくするために、複数のウィンドウを表示するのではなく、1つのウィンドウで様々な操作ができるようにしています。
そのために1つのウィンドウで複数の画面(フレーム)を切り替えて表示できるようにしています。
私がGUIアプリケーション開発で使用しているのはPythonのTkinterです。
本記事では、Tkinterによる複数の画面(フレーム)をボタン操作で切り替えて表示させる(画面遷移)方法を解説していきます。
Tkinterによる画面遷移の方法
Tkinterで作成するGUIアプリで画面遷移を実現するには2つの方法が考えられます。
- 表示しているFrame(フレーム)を削除して、新しいFrameを作成する
- メインウィンドウに複数のFrameを重ね、表示したいFrameを最前面に移動させる
1番はFrame(フレーム)を削除しているので、厳密に画面遷移とは言えませんが、見た目では画面が切り替わったように感じます。
2番は複数のFrameを切り替えて表示しているので、実際にアプリ開発をする場合はこの方法をしようしています。
Frame削除で画面切り替え
Frameの削除方法(delete()メソッド)
前述しているように、表示しているFrame(フレーム)を削除し、新しいFrameを表示することで画面が切り替わったように見せる方法です。
Frameの削除には、削除したいFrameに対してdestroy()メソッドを使用します。
-
frame.destroy()
サンプルプログラム
以下にFrameを削除して画面切り替えをしているように見せているTkinterアプリのプログラムソースを記します。
# tkinterのインポート
import tkinter as tk
import tkinter.ttk as ttk
def make():
global frame
frame_app.destroy()
# メインフレームの作成と設置
frame = ttk.Frame(root)
frame.pack(fill = tk.BOTH, pady=20)
# 各種ウィジェットの作成
label1_frame = ttk.Label(frame, text="メインウィンドウ")
entry1_frame = ttk.Entry(frame)
button_change = ttk.Button(frame, text="ウィンドウ変更", command=change)
# 各種ウィジェットの設置
label1_frame.pack()
entry1_frame.pack()
button_change.pack()
def change():
global frame_app
frame.destroy()
# メインフレームの作成と設置
frame_app = ttk.Frame(root)
frame_app.pack(fill = tk.BOTH, pady=20)
# 各種ウィジェットの作成
label1_frame_app = ttk.Label(frame_app, text="アプリウィンドウ")
entry1_frame_app = ttk.Entry(frame_app)
button_change_frame_app = ttk.Button(frame_app, text="ウィンドウ戻す", command=make)
# 各種ウィジェットの設置
label1_frame_app.pack()
entry1_frame_app.pack()
button_change_frame_app.pack()
if __name__ == "__main__":
# rootメインウィンドウの設定
root = tk.Tk()
root.title("tkinter application")
root.geometry("300x150")
# メインフレームの作成と設置
frame = ttk.Frame(root)
frame.pack(fill = tk.BOTH, pady=20)
# 各種ウィジェットの作成
label1_frame = ttk.Label(frame, text="メインウィンドウ")
entry1_frame = ttk.Entry(frame)
button_change = ttk.Button(frame, text="ウィンドウ変更", command=change)
# 各種ウィジェットの設置
label1_frame.pack()
entry1_frame.pack()
button_change.pack()
root.mainloop()
このアプリを起動し、画面遷移ボタンを押すと以下のように画面は切り替わります。
上記の画像からもわかるように、Frameを削除して新しいFrameを作成・表示するため、入力欄に入れた値は画面切り替え後には、空になってしまいます。
表示したいFrameを最前面に移動
最前面に移動する方法(tkraise()メソッド)
次に紹介する方法は、複数のFrame(フレーム)を1つのメインウィンドウに重ねて設置する方法です。
表示したいFrameはtkraise()メソッドを使用して、最前面に移動させます。
tkraise()メソッドは対象のFrameを最前面に移動させます。
-
frame.tkraise()
重ねる各Frameはgrid()メソッドで座標(0, 0)に設置します。
また引数にsticky="nsew"を入れて、メインウィンドウと同じサイズにしておくことも必要です。
-
frame.grid(row=0, column=0, sticky="nsew")
メインウィンドウのグリッド数を1×1にしておくと、Frameの配置がズレなくなります。
-
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
サンプルプログラム
以下に複数のFrame表示を切り替えるTkinterプログラムのソースを記します。
# tkinterのインポート
import tkinter as tk
import tkinter.ttk as ttk
def change_app():
frame_app.tkraise()
def change_main():
frame.tkraise()
if __name__ == "__main__":
# rootメインウィンドウの設定
root = tk.Tk()
root.title("tkinter application")
root.geometry("300x150")
# rootメインウィンドウのグリッドを 1x1 にする
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
# メインフレームの作成と設置
frame = ttk.Frame(root)
frame.grid(row=0, column=0, sticky="nsew", pady=20)
# 各種ウィジェットの作成
label1_frame = ttk.Label(frame, text="メインウィンドウ")
entry1_frame = ttk.Entry(frame)
button_change = ttk.Button(frame, text="アプリウィンドウに移動", command=change_app)
# 各種ウィジェットの設置
label1_frame.pack()
entry1_frame.pack()
button_change.pack()
# アプリフレームの作成と設置
frame_app = ttk.Frame(root)
frame_app.grid(row=0, column=0, sticky="nsew", pady=20)
# 各種ウィジェットの作成
label1_frame_app = ttk.Label(frame_app, text="アプリウィンドウ")
entry1_frame_app = ttk.Entry(frame_app)
button_change_frame_app = ttk.Button(frame_app, text="メインウィンドウに移動", command=change_main)
# 各種ウィジェットの設置
label1_frame_app.pack()
entry1_frame_app.pack()
button_change_frame_app.pack()
# frameを前面にする
frame.tkraise()
root.mainloop()
このアプリを起動し、画面遷移ボタンを押すと以下のように画面は切り替わります。
「Frame削除で画面切り替え」プログラムとは異なり、入力欄に入れた値は空にならずにそのまま残っています。
lambda(ラムダ式)で書き換え
lambda(ラムダ式)を使用して、アプリの拡張がしやすいようにしてみます。
今のままでは、重ねるFrameの数だけ関数を作成する必要があります。
これをlambda(ラムダ式)を使用して、一つの関数で複数のFrameに対応できるようにします。
# tkinterのインポート
import tkinter as tk
import tkinter.ttk as ttk
def change_app(window):
window.tkraise()
if __name__ == "__main__":
# rootメインウィンドウの設定
root = tk.Tk()
root.title("tkinter application")
root.geometry("300x150")
…
# 各種ウィジェットの作成
label1_frame = ttk.Label(frame, text="メインウィンドウ")
entry1_frame = ttk.Entry(frame)
button_change = ttk.Button(frame, text="アプリウィンドウに移動", command=lambda: change_app(frame_app))
…
# 各種ウィジェットの作成
label1_frame_app = ttk.Label(frame_app, text="アプリウィンドウ")
entry1_frame_app = ttk.Entry(frame_app)
button_change_frame_app = ttk.Button(frame_app, text="メインウィンドウに移動", command=lambda: change_app(frame))
…
# frameを前面にする
frame.tkraise()
root.mainloop()
ボタンウィジェットのcommandに対してlambdaを使い、関数の引数に表示したいFrameを与えています。
change_app関数では、引数で受け取ったFrame値をtkraise()メソッドで最前面に表示します。
まとめ
Tkinterによる複数の画面(フレーム)をボタン操作で切り替えて表示させる方法はいかがでしたか。
今回紹介した方法は、アプリを作成する上で非常に有用な技術です。
あまりネットにはtkraise()メソッドについて記載している記事は少ないですが、ぜひ使ってみてください。