KURORO BLOGのロゴ

このエントリーをはてなブックマークに追加
Tkinterで使われるtoplevelとは?Windowの説明を交えて徹底解説

Tkinterで使われるtoplevelとは?Windowの説明を交えて徹底解説

今回はTkinterで使われるtoplevelに関して、Windowの説明を交えて徹底解説いたします。toplevelに関して知りたい、コードを通してtoplevelを学びたい方へおすすめです。是非最後までご覧ください。

目次
  1. そもそもTkinterで使われるtoplevelとは?
  2. なぜtoplevel関数は必要?
  3. toplevel関数の定義
  4. toplevel関数で使われるoption
    1. background, bg
    2. highlightcolor, highlightbackground, highlightthickness
    3. cursor
    4. padx, pady
    5. borderwidth, bd
    6. relief
  5. サブWindowの生成を1つに限定
  6. サブwindowの詳細設定関数
    1. title
    2. geometry
    3. withdraw
    4. maxsize
    5. minsize
  7. まとめ
  8. 参考文献
目次を開く⬇︎

執筆者 - おすすめの記事3選

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

tkinterで使われるtoplevelとは、メインWindowに紐づくサブWindowを作成するものを意味します。

別名でtoplevel関数と呼ばれます。

具体的に画像を通して説明すると、

以上のようなWindowをそれぞれメインWindow、サブWindowと呼びます。

一見するとメインWindow、サブWindowともに同じように感じますね。ただメインWindowを閉じると、サブWindowも閉じられますが、サブWindowを閉じてもメインWindowは閉じられない点で異なります。(メインWindowを閉じた場合にサブWindowも閉じられるのは、メインWindowにサブWindowが紐づいているからです)

なぜtoplevel関数は必要?

サブWindowを作るために、メインWindowを作る時と同様、tk.Tk()を利用すれば上手くいくと考える方もいるかもしれません。

結論から説明すると、tk.Tk()を利用すると別のメインWindowを作ることはできます。しかしメインWindowに紐づくサブWindowを作ることはできません。

試しに以下のコードを利用して、サブWindowを作成してみてください。

1import tkinter as tk
2
3class Application(tk.Frame):
4    # サブWindowを取得する関数
5    def getSubWindow(self):
6        subWindow = tk.Tk()
7        # サブWindowへタイトルをつける。
8        subWindow.title('subWindow')
9        # Window(サブWindow)の画面サイズを設定する。
10        # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
11        subWindow.geometry("300x200+420+0")
12
13    def __init__(self, master=None):
14        # メインWindowの初期設定を行う。
15        super().__init__(master)
16        # メインWindowへタイトルをつける。
17        self.master.title("mainWindow")
18        # Window(メインWindow)の画面サイズを設定する。
19        # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
20        self.master.geometry("300x200+120+0")
21
22        self.getSubWindow()
23
24# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
25if __name__ == "__main__":
26    # Windowを生成する。
27    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
28    root = tk.Tk()
29    app = Application(master=root)
30
31    # Windowをループさせて、継続的にWindow表示させる。
32    # mainloopについて : https://kuroro.blog/python/DmJdUb50oAhmBteRa4fi/
33    app.mainloop()

メインWindowを閉じても、サブWindowは連動して閉じられないことがわかります。

以上のことからtoplevel関数の利用が必要になります。

toplevel関数の定義

toplevel関数は、

1tk.Toplevel(option1, option2, ...)

で定義されます。

例えば、以下のようなコードを作成すると

1import tkinter as tk
2
3class Application(tk.Frame):
4    # サブWindowを取得する関数
5    def getSubWindow(self):
6        # メインWindowに紐づくサブWindowを作成する。
7        subWindow = tk.Toplevel()
8        # サブWindowへタイトルをつける。
9        subWindow.title('subWindow')
10
11        # Window(サブWindow)の画面サイズを設定する。
12        # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
13        subWindow.geometry("300x200+420+0")
14
15        # subWindow(サブWindow)を親要素として、Button Widgetを作成する。
16        # command : ボタンを選択した場合に、実行する関数を設定。self.getSubWindowとする。
17        # text : テキスト情報
18        # Buttonについて : https://kuroro.blog/python/oFju6EngDtcYtIiMIDf1/
19        button = tk.Button(subWindow, command=self.getSubWindow, text='ボタン')
20        # subWindow(サブWindow)を親要素とした場合に、Button Widgetをどのように配置するのか?
21        # packについて : https://kuroro.blog/python/UuvLfIBIEaw98BzBZ3FJ/
22        button.pack()
23
24    def __init__(self, master=None):
25        # メインWindowの初期設定を行う。
26        super().__init__(master)
27        # メインWindowへタイトルをつける。
28        self.master.title("mainWindow")
29        # Window(メインWindow)の画面サイズを設定する。
30        # geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
31        self.master.geometry("300x200+120+0")
32        self.getSubWindow()
33
34# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
35if __name__ == "__main__":
36    # Windowを生成する。
37    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
38    root = tk.Tk()
39    app = Application(master=root)
40
41    # Windowをループさせて、継続的にWindow表示させる。
42    # mainloopについて : https://kuroro.blog/python/DmJdUb50oAhmBteRa4fi/
43    app.mainloop()

以下の画像のように、メインWindow, サブWindowを表示できます。

toplevel関数で使われるoption

toplevel関数で使われるoptionの種類としては

  • background, bg
  • highlightcolor, highlightbackground, highlightthickness
  • cursor
  • padx, pady
  • borderwidth, bd
  • relief

があります。順番に見ていきましょう。

※ optionの種類一覧を調べたい場合は、以下のようにコードを記述してご確認ください。

1import tkinter as tk
2
3# topLevelを生成する。
4topLevel = tk.Toplevel()
5# topLevelに関するoptionの種類一覧を取得する。
6print(topLevel.keys())

background, bg

background option, bg optionを利用すると、サブWindowの背景色を設定します。

backgroundとbg両方のoptionを用いて、値を設定した場合、後ろの引数に設定されるoptionが優先されます。

色に関しては、Tkinterの色の使い方とは?活用例から色の一覧をまとめて紹介!?で総括していますので、詳しく知りたい方は是非ご確認ください。

例えば「toplevel関数の定義」で紹介したコードのsubWindow = tk.Toplevel()箇所を、以下のように変更すると、

1# 別解法 ##########################
2# subWindow = tk.Toplevel()
3# subWindow.config(background='red') or subWindow.configure(background='red')
4##################################
5# 色について : https://kuroro.blog/python/YcZ6Yh4PswqUzaQXwnG2/
6subWindow = tk.Toplevel(background='red')

以下の画像のようにサブWindowを描画します。

highlightcolor, highlightbackground, highlightthickness

highlightcolor option, highlightbackground option, highlightthickness optionを利用すると、それぞれサブWindowへのフォーカスがあてられた時の囲い線の色, サブWindowへのフォーカスが外れた時の囲い線の色, サブWindowの囲い線の太さを設定できます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow = tk.Toplevel()箇所を、以下のように変更すると、

1# 別解法 ##########################
2# subWindow = tk.Toplevel()
3# subWindow.config(highlightthickness=20, highlightbackground="blue", highlightcolor="yellow") or subWindow.configure(highlightthickness=20, highlightbackground="blue", highlightcolor="yellow")
4##################################
5# 色について : https://kuroro.blog/python/YcZ6Yh4PswqUzaQXwnG2/
6subWindow = tk.Toplevel(highlightthickness=20, highlightbackground="blue", highlightcolor="yellow")

メインWindowへフォーカスが当てられた場合、以下の画像のようにサブWindowを描画します。

またサブWindowへフォーカスが当てられた場合、以下の画像のようにサブWindowを描画します。

cursor

cursor optionを利用すると、サブWindow内へマウスカーソルを移動すると矢印の見た目を変化できます。

見た目のバリエーションについてはこちらのサイトにまとまっていますので、ご確認ください。

例えば「toplevel関数の定義」で紹介したコードのsubWindow = tk.Toplevel()箇所を、以下のように変更して、

1# 別解法 ##########################
2# subWindow = tk.Toplevel()
3# subWindow.config(cursor="clock") or subWindow.configure(cursor="clock")
4##################################
5subWindow = tk.Toplevel(cursor="clock")

サブWindow内へマウスカーソルを移動すると、矢印の見た目が変更します。

padx, pady

padx option, pady optionを設定すると、枠の内側へ空白の幅を設定できます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow = tk.Toplevel()箇所を、以下のように変更すると、

1# 別解法 ##########################
2# subWindow = tk.Toplevel()
3# subWindow.config(padx=50, pady=50) or subWindow.configure(padx=50, pady=50)
4##################################
5subWindow = tk.Toplevel(padx=50, pady=50)

以下の画像のようにサブWindowを描画します。

borderwidth, bd

borderwidth option, bd optionを利用すると、サブWindowの枠の大きさを設定します。

borderwidthとbd両方のoptionを用いて、値を設定した場合、後ろの引数に設定されるoptionが優先されます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow = tk.Toplevel()箇所を、以下のように変更すると、

1# 別解法 ##########################
2# subWindow = tk.Toplevel()
3# subWindow.config(padx=50, pady=50, borderwidth=20) or subWindow.configure(padx=50, pady=50, borderwidth=20)
4##################################
5subWindow = tk.Toplevel(padx=50, pady=50, borderwidth=20)

以下の画像のようにサブWindowを描画します。

relief

relief optionを設定すると、サブWindowの枠のデザインを設定できます。

指定方法としては、

  • tk.RAISED
  • tk.SUNKEN
  • tk.FLAT
  • tk.RIDGE
  • tk.GROOVE
  • tk.SOLID

の6種類があります。

例えば「toplevel関数の定義」で紹介したコードを、以下のように変更すると、

1+    reliefList = [tk.RAISED, tk.SUNKEN, tk.FLAT, tk.RIDGE, tk.GROOVE, tk.SOLID]
2+    for relief in reliefList:
3-    subWindow = tk.Toplevel()
4+        subWindow = tk.Toplevel(borderwidth=20, relief=relief)
5
6-    subWindow.title('subWindow')
7+        subWindow.title('subWindow')
8-    subWindow.geometry("300x200+420+0")
9+        subWindow.geometry("300x200+420+0")
10-    button = tk.Button(subWindow, command=self.getSubWindow, text='ボタン')
11+        button = tk.Button(subWindow, command=self.getSubWindow, text='ボタン')
12-    button.pack()
13+        button.pack()

以下の画像のようにサブWindowを描画します。

サブWindowの生成を1つに限定

「toplevel関数の定義」で紹介したコードをPython環境で実行して、「ボタン」を選択すると以下の画像のようにサブWindowが複数生成されてしまいます。

サブWindowの生成を1つに限定するために、winfo_exists()関数を活用するとうまくいきます。

例えば「toplevel関数の定義」で紹介したコードを、以下のように変更すると、

1class Application(tk.Frame):
2    # サブWindowを取得する関数
3    def getSubWindow(self):
4+       # subWindowをグローバル変数とする。
5+       global subWindow
6+       # subWindowがNoneもしくはsubWindow(サブWindow)が存在しない場合
7+       # winfo_exists() : サブWindowが存在するのか判定する関数。True(サブWindowが存在する), False(サブWindowが存在しない)が返されます。
8+       if subWindow == None or not subWindow.winfo_exists():
9-       subWindow = tk.Toplevel()
10+            subWindow = tk.Toplevel()
11-       subWindow.title('subWindow')
12+            subWindow.title('subWindow')
13-       subWindow.geometry("300x200+420+0")
14+            subWindow.geometry("300x200+420+0")
15-       button = tk.Button(subWindow, command=self.getSubWindow, text='ボタン')
16+            button = tk.Button(subWindow, command=self.getSubWindow, text='ボタン')
17-       button.pack()
18+            button.pack()
19# Tkinter初学者参考 : https://docs.python.org/ja/3/library/tkinter.html#a-simple-hello-world-program
20if __name__ == "__main__":
21    # Windowを生成する。
22    # Windowについて : https://kuroro.blog/python/116yLvTkzH2AUJj8FHLx/
23    root = tk.Tk()
24
25+   # subWindowに関する変数の初期化
26+   subWindow = None

以下の画像のように、サブWindowの生成を1つに限定できます。

サブwindowの詳細設定関数

サブwindowの詳細設定関数として、

  • title
  • geometry
  • withdraw
  • maxsize
  • minsize

が存在します。順に見ていきましょう。

title

titleを利用すると、サブWindowのtitleを設定できます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow.title('subWindow')箇所を、以下のように変更すると、

1subWindow.title('testtest')

以下の画像のように、titleを'testtest'に変更できます。

geometry

geometryを利用すると、サブWindowの位置や大きさを調整できます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow.geometry("300x200+420+0")箇所を、以下のように変更すると、

1# width : アプリ画面(Window)の幅
2# height : アプリ画面(Window)の高さ
3# xPoint : パソコン画面の左上隅を原点(0, 0)とした、x座標
4# yPoint : パソコン画面の左上隅を原点(0, 0)とした、y座標
5# 原点とは? : http://kentiku-kouzou.jp/suugaku-genten.html
6# .geometry(widthxheight+xPoint+yPoint")
7# geometryについて : https://kuroro.blog/python/rozH3S2CYE0a0nB3s2QL/
8subWindow.geometry("500x300+420+0")

以下の画像のように、サブWindowのサイズを大きく表示できます。

geometry関数に関して詳しく知りたい場合は、Tkinterで使われるgeometryとは?コードを通して活用方法を徹底解説の記事をご確認ください。

withdraw

withdrawを利用すると、サブWindowをパソコン画面から非表示にできます。

例えば「toplevel関数の定義」で紹介したコードのsubWindow.geometry("300x200+420+0")箇所の下へ、以下のコードを追記すると、

1  subWindow.geometry("300x200+420+0")
2+ subWindow.withdraw()

以下の画像のように、サブWindowをパソコン画面から非表示にできます。

maxsize

maxsizeを利用すると、サブWindowの最大幅・最大の高さを設定できます。

例えば「toplevel関数の定義」で紹介したコード内のsubWindow.geometry("300x200+420+0")下へ以下のコードを追加すると、

1   subWindow.geometry("300x200+420+0")
2+  # maxsize : サブWindowの最大幅・最大の高さを設定する。
3+  # 第一引数 : 最大幅
4+  # 第二引数 : 最大の高さ
5+  subWindow.maxsize(500, 200)

以下の画像のように、サブWindowを幅500, 高さ200まで広げられます。

minsize

minsizeを利用すると、サブWindowの最小幅・最小の高さを設定できます。

例えば「toplevel関数の定義」で紹介したコード内のsubWindow.geometry("300x200+420+0")下へ以下のコードを追加すると、

1   subWindow.geometry("300x200+420+0")
2+  # minsize : サブWindowの最小幅・最小の高さを設定する。
3+  # 第一引数 : 最小幅
4+  # 第二引数 : 最小の高さ
5+  subWindow.minsize(100, 200)

以下の画像のように、サブWindowを幅100, 高さ200まで小さくできます。

まとめ

  • tkinterで使われるtoplevelとは、メインWindowに紐づくサブWindowを作成するものを意味します。
  • 別名でtoplevel関数と呼ばれます。
  • winfo_exists()関数を活用すると、サブWindowを複数表示しなくて済みます。

参考文献

記事に関するお問い合わせ