つきすけ の コーディング記

細かいところで嫌にならないように、小さいことでも解説していくブログ。たまに関係ないことも書く。

Python の Tkinter で画面遷移する

ボタンを押したら別画面に移動したい。
今回は以下の二つの方法を試す。どっち使うかはお好みで。

  1. canvasを変える
  2. ウィンドウごと変える

準備

import tkinter

def transition_button(widget):
    # ここにボタンを押した時の処理を書く。                                      
    print("clicked")

# ウィンドウの作成                                                              
window = tkinter.Tk()
window.geometry("400x400")
window.title("Screen Transition")

# 遷移前の画面の作成                                                            
canvas1 = tkinter.Canvas(background="#cea", width=400, height=400)
canvas1.place(x=0, y=0) # キャンバス                                            
label1 = tkinter.Label(canvas1, text="遷移する前の画面です。") # テキスト       
label1.place(x=200, y=150, anchor=tkinter.CENTER)
button = tkinter.Button(canvas1, text="遷移するボタン", command=lambda:transition_button(canvas1)) # 遷移ボタン                                                
button.place(x=200, y=250, anchor=tkinter.CENTER)

window.mainloop()

実行結果 ボタンを押すとひとまずコンソールに"clicked"と表示される。表示されればボタンが関数と連動しているということ。

f:id:Tsukisuke:20200219095334p:plain
遷移前の画面

canvasを変える

canvas1という名前で遷移画面を設定したが、このcanvas1を消すか非表示にするかして、canvas2という新たなcanvasを重ねる方法。なお、canvas1を消さずともcanvas2を上に重ねるだけで隠すことは可能だが、表示方法によってはうまい具合に避けられたりなどすることもあるので、あまりオススメはしない。

というわけで、ボタンの動作関数(transition_button)の中を次のように書き直す。

def transition_button(widget):
    widget.place_forget() # canvas(widget)を隠す                          
    canvas2 = tkinter.Canvas(background="#eca", width=400, height=400)
    canvas2.place(x=0, y=0)
    label2 = tkinter.Label(canvas2, text="遷移後の画面です。")
    label2.place(x=200, y=150, anchor=tkinter.CENTER)

このコードではwidget.place_forget()ウィジェット(canvas等)を"非表示"にする。forgeは.pack()も.grid()もあるようだ。
完全に削除したい場合はwidget.destroy()とする。これはあとでもう一度表示する可能性がない場合などに使える。

実行結果

f:id:Tsukisuke:20200219100753g:plain
画面遷移の様子

ウィンドウごと変える

ウィンドウもウィジェットの一種なので、Canvasとやることは対して変わらない。今回は元々のwindowをdestroy(削除)して、新しいウィンドウ常に遷移後の画面を表示してみる。
以下、ボタン関数の中身。

def transition_button(widget):
    widget.destroy()
    window2 = tkinter.Tk()
    window2.geometry("400x400")
    window2.title("Screen 2")
    canvas2 = tkinter.Canvas(background="#eca", width=400, height=400)
    canvas2.place(x=0, y=0)
    label2 = tkinter.Label(canvas2, text="遷移後の画面です。")
    label2.place(x=200, y=150, anchor=tkinter.CENTER)

また、今回は上の関数の引数にはwindowそのものを渡すので、ボタンを定義したところを書き換える。

button = tkinter.Button(canvas1, text="遷移するボタン", command=lambda:transition_button(window)) # 遷移ボタン

こうなる。

f:id:Tsukisuke:20200219164452g:plain
画面遷移の様子

補足

今回は新しい画面をすべてボタン関数の中に書いたが、大規模なプロジェクトになった場合は、
先に遷移後の画面を書いて非表示にしておく -> ボタンで表示にする
が賢いだろう。わざわざ補足するほどのことでもないか...