tkinterではwidget(例:Frame、Canvas)を配置するには3つの方法 grid, pack, placeがあります。
今回はpackに焦点を当ててwidgetの配置方法についてまとめていきます。
前準備
pack()
の使い方について見る前に、template.py
とapp.py
を用意します。この2つのプログラムを使ってpack()
の使い方について見ていきます。
template.py
template.py
はアプリケーションの雛形として用意しました。ここでは、アプリケーションのタイトル、起動時のアプリケーションの位置、アプリケーションの拡大拡小の設定、アプリケーションのアイコンについて設定をすることができます。設定はtemplate.py
を継承したクラスでするようにしてあります。
関連記事 - はじめてのtkinter ウィンドウを作って表示させる
app.py
template.py
のTemplateクラスを継承しています。今回は特にアプリケーションのタイトル、位置、拡大拡小、アイコンの設定については行いません。createWidgets
でWidgetの作成、attachWidgets()
で作成したWidgetをウィンドウに配置していきます。
packの使い方
今回、pack()
の使い方を見るに当たって2つのFrameを用意しました。frame_1
にはLabel、frame_2
にはButtonを配置したいと思います。
LabelとButtonを作る前に、ひとまず2つのFrameをを生成してウィンドウに配置してみます。
createWidgets()
とattachWidgets()
をそれぞれ変更しました。変更後のコードを実行してみます。
$ python app.py
下のようなウィンドウが起動するはずです。
特にオプションを指定しなくてもFrameが配置されていますね。
次に、LabelとButtonを生成して用意した2つのフレームに配置していきます。
3つのLabelと2つのButtonを生成してpack()
を使ってそれぞれFrameに配置してみました。この状態でプログラムを実行すると下のウィンドウが起動します。
pack()
をオプションなしで使用すると、pack()
を呼び出した順に上からwidgetが配置されていますね。
あと、オプションなしだとwidgetのサイズに合わせてFrameのサイズが変わっているようです。オプションの設定をすれば見栄えのいいものに変えることができそう。
これからpack()
のオプションについて詳しく見ていきます。
関連記事① - [tkinter] Labelを使ってみる
関連記事② - [tkinter] Buttonを使ってみる
関連記事③ - [tkinter] Frameを使ってみる
side(widgetをどこから詰め込むのか決める)
side
を設定することで、widgetをparent(親ヴィジット)のどこから詰めるのか決めることができます。デフォルトではTOP
になっており、上から詰める設定になっています。そのため、さきほど実行したプログラムではLabelとButtonが上から順に配置されていたわけです。
他の選択肢として、左から詰めるLEFT
、右から詰めるRIGHT
、下から詰めるBOTTOM
があります。
試しに、FlameにLEFT
を使ってみます。
コードを変更して実行すると、
このようなウィンドウが起動します。さきほどはframe_1
が上側、frame_2
が下側に配置されていましたが、左詰めの設定をしたことで、frame_1
、frame_2
と順に左詰めになっています。
次に、各Frameに入れたLabelとButtonにside
の設定をしてみます。
コードを変更して、実行すると下のようになりました。
このようにside
の設定をすることでwidgetをどこから詰めるのかを決めることができました。
anchor(親ヴィジットのどこに置くか決める)
anchor
はwidgetを配置先の親ヴィジットのどこに置くかを決めるために使います。デフォルトではCENTER
になっています。
他には、右E
、左W
、上N
、下S
、右上NE
、右下SE
、左上NW
、左下SW
があります。
試しに、label_sample
のanchor
を下に設定してプログラムを実行してみます。
下のウィンドウが起動しました。
今回はLabelのサンプルのところに変化を加えました。
side
の説明のところで最後に使ったソースコードを実行したときと少し違う点があるのがわかりますか?
side
のところだとサンプルの下に隙間がありましたが、今回anchor
をtk.S
と設定したのでlabel_sample
の位置が下に移動して配置されていることがわかります。
このように、anchor
を指定するとwidgetを親ヴィジットのどのあたりに配置するのかを決めることができます。
ipadx, ipady(内側のpadding)
ipadx
とipady
はそれぞれwidgetの内側の高さと横の長さを設定することができます。デフォルトでは0になっています。
試しに、button_sample
のipadx
とipady
の値を変えてみます。
このように変更して実行すると下のウィンドウが起動します。
padx, pady(外側のpadding)
padx
とpady
はそれぞれwidgetの外側の高さと横の長さを設定することができます。デフォルトでは0になっています。
試しに、label_tkinter
のpady
の値を変えてみます。
このように変更して実行すると下のウィンドウが起動します。
tkinter
のLabelの上下にそれぞれpady
で指定した値の長さが設定されています。
padx
とpady
ですが、実はもう少し細かい設定をすることができます。
label_tkinter
のpadx
とpady
を上のように変更してみました。
このプログラムを実行すると、
このようになりました。
padx
とpady
はそれぞれpadx=(左、右)
、pady=(上、下)
と細かく設定をすることができるんです。
fill(隙間を埋める)
fill
を使うことで隙間を埋めることができます。例えば、さきほど実行したプログラムだとframe_1
の上下が空いていましたよね。
こんなときに隙間を埋めることができるのがfill
なんです。使い方は超簡単です!デフォルトではNONE
になっているのをBOTH
にするだけ。
隙間があるframe_1
のfill
をBOTHに設定してプログラムを実行すると、
はい、さっきまで隙間があったのにちゃんと隙間が埋まっています!!
fill
は他にもX
とY
を設定することができます。Xだと水平方向の隙間を埋める、Yだと垂直方向に隙間を埋める、BOTHだと水平方向と垂直方向の隙間を埋めることができます。
expand(拡大)
この記事の最後に参考記事を載せていますが、その参考記事を見る限りexpand
はparent(親ヴィジット)を拡大したときに生まれるwidget周りの隙間をどうするかを設定すると書かれています。しかし、試してみるとwidget周りの隙間は埋めていない感じがしました。
見た感じparentを拡大したときに、widgetの位置がFalseなら固定、Trueならparentの拡大に伴ってwidgetの位置が設定通りに移動している感じがしました。
あ、ちなみに私が書いたtemplate.py
ではウィンドウの拡大拡小ができない設定をしているので、app.py
の__init__()
を以下のように変更してください。
おわり
pack()
の使い方について紹介しました。
tkinterについて他にもいろいろ書いているので、ご興味があるかたはぜひ以下の記事を見てみてください。
参考記事① - The Tkinter Pack Geometry Manager
参考記事② - Python | pack() method in Tkinter - GeeksforGeeks