Pythonのtkinterのグリッド(grid)を使って要素を整列、レイアウトを綺麗にする方法

スポンサーリンク

前回のTkinterのチュートリアルでは、Tkinterのテキストウィジェットを取り上げました。

今回は、Tkinterのグリッドマネージャを使用する例を見てみましょう。

しかし、特に多くの人が pack マネージャを使用しているのを見て、質問したいことがあるかもしれません。

スポンサーリンク

なぜTkinter Grid Managerを使うのか?

これまでのチュートリアルでは、アプリケーションのジオメトリを管理するために pack ジオメトリマネージャを使用してきました。

しかし、多くのオブジェクトに対してスムーズに動作させるのは難しい作業です。

そこでTkinterは他のパッキングマネージャを導入し、私たちの生活を少し楽にし、また、いつ何を使うかについて柔軟性を持たせるようにしました。

Tkinterのグリッドマネージャは実は一番習得しやすく、Tkinterアプリケーションを作り始めるなら一番おすすめです。

それでは、実際にグリッドマネージャをアプリケーションで使ってみましょう。

注意: 同じ Tkinter アプリケーションで複数のパッキングマネージャを使用しないでください。

これは意図しないバグを引き起こす可能性があり、まったくお勧めできません。

ひとつのアプリケーションには、ひとつのパッキングマネージャのみを使用してください。

Tkinterのグリッド・ジオメトリ・マネージャを使用する

以下のレイアウトをGridマネージャを使ってデザインしてみましょう。

import tkinter as tk
 
master = tk.Tk()

このレイアウトでは、2つのエントリウィジェットと、それぞれのラベル、そして下にボタンウィジェットを配置します。

また、右側に画像を追加し、その画像用のボタンウィジェットも追加します。

このようなレイアウトは pack を使って管理するのは難しいですが、grid を使えば簡単に作ることができます!手順は簡単です。

手順はとてもシンプルです。

必要なウィジェットをすべて作成し、それらをどのように配置するかを grid マネージャに指示するだけです。

まずはマスターオブジェクトを作りましょう。

label_object.grid(row, col)

まず、ラベルを 2 つ作成しましょう。

一番左に配置する必要があるので、grid マネージャにそれぞれの行番号に配置するように指示します。

ラベルは列番号 0、行番号 0 と 1 のインデックスに必要です。

ラベルを作成した後、grid を使用して直接ラベルをパックすることができます。

tk.Label(master, text="Label 1").grid(row=0, column=0)
tk.Label(master, text="Label 2").grid(row=1, column=0)

ということで、直接以下のように書くことができます。

e1 = tk.Entry(master)
e2 = tk.Entry(master)

それでは、2つのラベルのそれぞれにエントリを追加してみましょう。

e1.grid(row=0, column=1)
e2.grid(row=1, column=1)

エントリオブジェクトを作成しましたが、次に grid にオブジェクトをそれぞれの位置に配置するように指示する必要があります。

単純に entry_obj.grid() を呼び出すだけです! これは pack と似ていますが、全体的にもっとスムーズに使うことができます。

import tkinter as tk
 
# Create the master object
master = tk.Tk()
 
# Create the label objects and pack them using grid
tk.Label(master, text="Label 1").grid(row=0, column=0)
tk.Label(master, text="Label 2").grid(row=1, column=0)
 
# Create the entry objects using master
e1 = tk.Entry(master)
e2 = tk.Entry(master)
 
# Pack them using grid
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
 
# The mainloop
tk.mainloop()

この後、tk.mainloop()を使ってtkinterのメインループを追加することができます。

この時点までの完全なコードを掲載します。

button1 = tk.Button(master, text="Button 1")
button1.grid(columnspan=2, row=2, column=0)

結果は以下の通りです。

from PIL import Image, ImageTk
 
# Create the PIL image object
image = Image.open("debian.png")
photo = ImageTk.PhotoImage(image)
 
# Create an image label
img_label = tk.Label(image=photo)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
img_label.image = photo
 
img_label.grid(row=0, column=2)

さて、どうでしょう。

これで期待通りに動作しているようです。

では、この下にボタンを追加してみましょう。

出力

# Create another button
button2 = tk.Button(master, text="Button 2")
button2.grid(columnspan=2, row=2, column=2)

これで、左側がカバーされました。

右側には画像とボタンを追加しましょう。

前回のチュートリアルで画像を表示する際の問題点を説明しましたが、自動的なガベージコレクションを避けるために PhotoImage オブジェクトへの参照を保持する必要があります!

import tkinter as tk
from PIL import Image, ImageTk
 
# Create the master object
master = tk.Tk()
 
# Create the label objects and pack them using grid
tk.Label(master, text="Label 1").grid(row=0, column=0)
tk.Label(master, text="Label 2").grid(row=1, column=0)
 
# Create the entry objects using master
e1 = tk.Entry(master)
e2 = tk.Entry(master)
 
# Pack them using grid
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
 
button1 = tk.Button(master, text="Button 1")
button1.grid(columnspan=2, row=2, column=0)
 
# Create the PIL image object
image = Image.open("debian.png")
photo = ImageTk.PhotoImage(image)
 
# Create an image label
img_label = tk.Label(image=photo)
# Store a reference to a PhotoImage object, to avoid it
# being garbage collected! This is necesary to display the image!
img_label.image = photo
 
img_label.grid(row=0, column=2)
 
# Create another button
button2 = tk.Button(master, text="Button 2")
button2.grid(columnspan=2, row=2, column=2)
 
# The mainloop
tk.mainloop()

最後に、一番下にボタンを追加しましょう。

Layout
Layout

さて、完成したプログラムをここに掲載します。

Tkinter Grid Sample
Tkinter Grid Sample

結果は以下の通りです。

Tkinter Grid Complete Layout
Tkinter Grid Complete Layout

ついに、レイアウトが完成しました! ウィジェットを作成して grid に正しい位置に配置するように指示するだけなので、とても簡単です!

まとめ

この記事では、Tkinterアプリケーションにウィジェットを追加し、Tkinter Grid Geometry Managerを使用してレイアウトをデザインする方法を学びました。

今後もTkinterのコンテンツにご期待ください!

タイトルとURLをコピーしました