KURORO BLOGのロゴ

このエントリーをはてなブックマークに追加
【図解付き!?】Tkinterで使われるmainloopをわかりやすく解説

【図解付き!?】Tkinterで使われるmainloopをわかりやすく解説

今回はTkinterで使われるmainloopを、図解を用いてわかりやすく解説いたします。なんとなくmainloopを使っていた、mainloopに関して深く知りたい方へおすすめです。是非最後までご確認ください。

目次
  1. そもそもTkinterで使われるmainloopとは?
  2. mainloop関数の定義
  3. Tkinterで使われるmainloop関数の役割
    1. 継続的にアプリを表示しづつける
    2. イベントの処理を行う
  4. イベント処理の仕組み
  5. まとめ
  6. 参考文献

そもそもTkinterで使われるmainloopとは?

Tkinterで使われるmainloopとは、継続的にアプリを表示しづつけるために必要なものを意味します。

別名でmainloop関数と呼ばれます。アプリを作成する上で非常に大切な関数になります。

mainloop関数の定義

mainloop関数は、

1mainloop()

で定義されます。戻り値はありません。

mainloop関数を実行すると、名前からも想像できるように、Window(画面)を閉じるまで、mainloop関数内を永久にループしています。

よってmainloop関数の後に記述した、以下のようなコードは、Window(画面)が閉じられるまで実行されません。

1import tkinter as tk
2
3if __name__ == "__main__":
4    # Windowを生成する。
5    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
6    root = tk.Tk()
7    root.mainloop()
8    # Window(画面)が閉じられるまで、mainloop関数以降の処理は実行されない。mainloop関数内でループが発生しているため。
9    print('aiueo')

またmainloop関数はWindow, Frame, Widget全てに対して利用可能です。

ただmainloop関数の後に記述したコードは、Window(画面)が閉じられるまで実行されないので、

  • 最終行でWindowに対してmainloop関数を呼んで、わかりやすい設計にする
  • 一度だけ呼び出す。何度もmainloop関数を利用して、処理を複雑にしない

場合が多いです。

Windowに対してmainloop関数を呼ぶ

1import tkinter as tk
2
3# Windowを取得する。
4def getWindow(root):
5    # Windowに対してmainloop関数を呼ぶ。
6    root.mainloop()
7
8# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
9if __name__ == "__main__":
10    # Windowを生成する。
11    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
12    root = tk.Tk()
13    getWindow(root)

Frameに対してmainloop関数を呼ぶ

1import tkinter as tk
2
3# Frameを取得する。
4def getFrame(root):
5    # Windowを親要素として、frame Widget(Frame)を作成する。
6    # Frameについて : https://kuroro.blog/python/P20XOidA5nh583fYRvxf/
7    frame = tk.Frame(root)
8    # Frameに対してmainloop関数を呼ぶ。
9    frame.mainloop()
10
11# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
12if __name__ == "__main__":
13    # Windowを生成する。
14    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
15    root = tk.Tk()
16    getFrame(root)

Widgetに対してmainloop関数を呼ぶ

1import tkinter as tk
2
3# Widgetを取得する。
4def getWidget(root):
5    # Windowを親要素として、frame Widget(Frame)を作成する。
6    # Frameについて : https://kuroro.blog/python/P20XOidA5nh583fYRvxf/
7    frame = tk.Frame(root)
8
9    # frame Widget(Frame)を親要素として、text Widgetを作成する。
10    # Textについて : https://kuroro.blog/python/bK6fWsP9LMqmER1CBz9E/
11    text = tk.Text(frame)
12    # Widgetに対してmainloop関数を呼ぶ。
13    text.mainloop()
14
15# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
16if __name__ == "__main__":
17    # Windowを生成する。
18    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
19    root = tk.Tk()
20    getWidget(root)

Window, Frame, Widgetに関して詳しく知りたい場合は、Tkinterで使われるbuttonとは?コード例を交えて実践的な活用方法を解説の「Tkinterの構成要素」項目をご確認ください。

Tkinterで使われるmainloop関数の役割

Tkinterで使われるmainloop関数の役割として

  • 継続的にアプリを表示しづつける
  • イベントの処理を行う

の2つがあります。順に見ていきましょう。

継続的にアプリを表示しづつける

本題を説明する前に、まずは簡単なPythonプログラムを確認しましょう。

1# 足し算を行う関数
2# 第一引数 : number
3# 第二引数 : number
4# 戻り値 : number
5def calcPlus(preNum, nextNum):
6    return preNum + nextNum
7
8print(calcPlus(1, 5))

上記のプログラムは第一引数と第二引数を足し算するプログラムです。

以下の手順で実行され、

  1. 開始
  2. calcPlus(1, 5)関数が呼ばれる。
  3. return preNum + nextNumを実行する。
  4. print表示する。
  5. 終了

プログラムを終了します。

つまりプログラムは、上から下へ順番に実行し、処理するコードがなくなると終了します。

Tkinterに関しても同じで、例えば以下のようなプログラムは、root = tk.Tk()が実行されると終了(アプリを閉じる)します。

1import tkinter as tk
2# Windowを生成する。
3# Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
4root = tk.Tk()

もちろん直ぐにプログラムを終了(アプリを閉じる)したい場合は、以上のように設計しても構いません。

しかし実際はアプリを表示しづつけた状態で、利用(ボタンの選択や文字入力)してもらうことがほとんどです。アプリを表示しづつけるためにもmainloop関数を活用しましょう。

mainloop関数を利用せず、以下のコードのように、while文を用いてアプリを表示し続けることを考えた方もいるかもしれません。しかしmainloop関数にはもう一つ、イベントの処理を行う機能も持っているため、while文だけではアプリを表示し続けることはできません。

1# helloをloopする関数
2def getLoop():
3    while True:
4        print('hello')
5
6# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
7if __name__ == "__main__":
8    # Windowを生成する。
9    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
10    root = tk.Tk()
11    getLoop()

アプリの画面が全く表示されない場合は、mainloop関数の実行を忘れていないか確認するといいでしょう。

イベントの処理を行う

今までの話から

  • mainloop関数は、Window(画面)を閉じるまで、mainloop関数内を永久にループする
  • mainloop関数を利用して、mainloop関数内を永久にループすることでアプリを継続的に表示し続ける

ことをお伝えしました。

今回の章では、mainloop関数内で実行されるイベントの処理を行うに関して解説いたします。

まずはイベントに関して定義しましょう。

イベントとは、

  • Tkinterアプリ内でボタンを押す
  • Tkinterアプリ内で文字を入力する
  • Tkinterアプリ内でマウスを動かす

などの動作を意味します。

続いてイベントの処理に関して定義しましょう。

イベントの処理とは、イベントが起こった場合に、イベントに紐づく関数を実行することを意味します。

要するに、mainloop関数は、

  • Window(画面)を閉じるまで、mainloop関数内を永久にループすることで、イベントを監視できるようになる
  • イベントが起こった場合に、イベントに紐づく関数を実行する

ために利用されます。

イベントに紐づく関数は、自身で作った関数やライブラリなど全般を意味します。

イベントと関数を紐付ける方法として、よくbind関数を利用します。

bind関数に関しては、【コード付】Tkinterで使われるbindとは?bindの仕組みを交えて解説でまとめていますので、詳しく知りたい方は是非ご確認ください。

イベント処理の仕組み

「イベント処理の仕組み」の章では、mainloop関数内で実装される、イベント処理の仕組みに関して説明いたします。

画像でもわかる通り、mainloop関数は、

  • ループ処理を行っている。
  • 「イベントの確認」、「イベント群」、「イベントを実行(イベントに紐づく関数を実行)」の3つで構成される。
  • イベントがない場合は、イベントの実行(イベントに紐づく関数の実行)を行わない。
  • イベントを実行する順番を管理するために、「イベント群」を管理している。

を継続的に行います。

またmainloop関数は、「イベントを実行(イベントに紐づく関数を実行)」が完了するまで、続くイベント(イベントに紐づく関数)は実行できないので、アプリを構成する際は、以上のことを念頭に開発することが必要です。

まとめ

  • Tkinterで使われるmainloopとは、継続的にアプリを表示しづつけるために必要なものを意味します。
  • プログラムは、上から下へ順番に実行し、処理するコードがなくなると終了します。
  • mainloop関数は、「イベントの実行(イベントに紐づく関数の実行)」が完了するまで、続くイベントを実行できない。

参考文献