はじめに
今回は、tkinterモジュールの.pack()について掘り下げて解説します。
Python+tkinterの導入が済んでおり、基本操作が行える事を前提で進めます。
↓前提知識はこちらをご覧ください↓



個人的に、ウィジット配置は「.place()」が一番使いやすいと思います。
ウィジットを配置する(x / y)
place()はウィジットの位置を指定して配置します。
x = で横位置 / y= で縦位置をpxで指定。
↓は高さだけズレるように、y=の値を40×nのような形で設定しました。

すると… ウィジットが並んで配置されます。

以上が、ウィジットを配置する(x / y)処理の解説です。
ウィジットの基準位置を設定する(anchor =)
ウィジットの位置の基準はanchor =で指定できます。
デフォルトだと左上を意味する “NW” 設定です。

また、anchor =は下記の2通りの書き方ができます。
・anchor = tkinter.NW
・anchor = "nw"
この2つは同じ意味で、初期状態と同じ基準位置が設定されます。
なので、見た目的な変化は起こりません。

そしたら、anchor = の値を適当に操作します。
位置の決まり方は下図の通り(方角が元ネタです)

【anchor = での方角指定方法】
・anchor = "nw" → 左上を基準位置に設定
・anchor = "n" → 上中央を基準位置に設定
・anchor = "ne" → 右上を基準位置に設定
・anchor = "e" → 左中央を基準位置に設定
・anchor = "se" → 左下を基準位置に設定
・anchor = "s" → 下中央を基準位置に設定
・anchor = "sw" → 左下を基準位置に設定
・anchor = "w" → 左中央を基準位置に設定
・anchor = "center" → 中央を基準位置に設定
【別の表記方法】
・anchor = "nw" → tkinter.N
・anchor = "n" → tkinter.NE
・anchor = "ne" → tkinter.E
・anchor = "e" → tkinter.SE
・anchor = "se" → tkinter.S
・anchor = "s" → tkinter.SW
・anchor = "sw" → tkinter.W
・anchor = "w" → tkinter.NW
・anchor = "center" → tkinter.CENTER
こちらを設定。

すると、基準位置が変わるのでウィジットの配置が変わります。


anchor = は使いにくいと言いますか…
変えるとややこしいので、基本は左上から変えないのです。
なので、使う機会は少ないです。
以上が、ウィジットの基準位置を設定する(anchor =)の解説です。
ウィジットの領域を広げる(width / height)
ウィジットの領域は、下記の方法で設定できます。
・width → 横幅を指定(単位はpx)
・height → 縦幅を指定(単位はpx)

こちらを設定。
すると、ウィジットの大きさが変わります。

以上が、ウィジットの領域を広げる(width / height)の解説です。
ウィジットが重なった場合の挙動
ウィジットが重なるように、位置と大きさを設定。

すると、Label_1 → 2 → 3の順に重なります。
これば処理順によって決まった順番です。


プログラムは基本、上から下に処理されます。
なのでLabel_1 → 2 → 3の順番になります。
そしたら、Label_1の位置を一番下に移動。

すると、描画順が変わり、重なり方が変わりました。
(Label_1がLabel_2より “前” に来ました)

以上が、ウィジットが重なった場合の挙動の解説です。
画面サイズに合わせて配置を変える(relx/y)
これまでの処理はpxで位置と大きさを指定してました。
なので、画面サイズを変えても変化は発生しません。

そこで、まず位置を「relx / y」で設定します。
設定方法は下記の通り。
【画面幅に合わせた位置設定(relx/y)】
・relx → 左端を0、右端を1としてその間で "位置" を設定
・rely → 上端を0、下端を1としてその間で "位置" を設定

小数を使って配置を微調整する形になります。
そしたら、x/yの代わりに「relx / y」を使って位置を設定します。

これで、画面サイズに合わせて配置が決まります。

画面を動かすと、下図の通り動きます。


これで、俗にいうレスポンシブデザインが作れます。
(画面の大きさに合わせて、UIが変わるデザインの意)
以上が、画面サイズに合わせて配置を変える(relx/y)処理の解説です。
画面サイズに合わせて領域を変える(relwidth/height)
画面サイズに合わせた大きさも「relwidth / height」で設定できます。
設定方法は下記の通り。
【画面幅に合わせた位置設定(relx/y)】
・relwidth → 左端を0、右端を1としてその間で "大きさ" を設定
・relheight → 上端を0、下端を1としてその間で "大きさ" を設定

こちらも、小数を使って配置を微調整する形になります。
そしたら、width/height の代わりに「relwidth / relheight」を使って大きさを設定します。

これで、画面サイズに合わせて大きさを変えることができます。

これで、画面サイズに合わせて領域サイズを変更できます。
※小さくすると、テキストは見切れるので注意。

以上が、画面サイズに合わせて領域を変える(relwidth/height)処理の解説です。
画面サイズに合わせてn等分して配置する方法(/n)
rel系の処理を上手く使うと、画面サイズに合わせてn等分したウィジットを作れます。
下記のように設定。
【画面サイズに合わせてn等分する方法(ここでは横幅を設定)】
・relwhidth = でn等分する数を設定(「1/n」表記)
・relx = でn等分した数を打ち込み
そして「*0~」で場所を指定(「1/n×0~」表記)
下図のように設定。
(relheightとrelyは適当な値を設定)

すると、画面の横幅を3等分したウィジットを作れます。

また「/5」設定にすると、5等分も可能です。

relx = 「*0,2,4」を設定すると、1,3,5の位置に5等分したウィジットを配置できます。

高さも同様の設定が可能です。
ここでは「/6」で設定。
位置を「*5」に設定。

すると、綺麗な大きさでウィジットを配置できます。

横幅の要素を「/5」して「*0~4」の値を設定。

すると、5等分にする事もできます。

以上が、画面サイズに合わせてn等分して配置する方法です。

この設定がレスポンシブデザインを細かく作り込むうえで便利なので…
私はウィジェット配置は「.place()」が最強だと考えてます。
次は、この設定をより使いやすくし…
“余白” まで作れるようになる考え方を紹介します。
画面サイズに合わせてn%で大きさと位置を決める(/100×n)
n等分する処理で「/100」に設定すると、画面サイズを1%単位で調整できます。

0.1%刻みで調整したいなら「/1000」
0.01%刻みで調整したいなら「/10000」にします。
これを使えば横幅を÷5した要素の周囲に2%の余白を作ることができます。
作り方は下記の通り。
【2%の余白を作る処理の流れ】
・relwidthの値に「/100」を入れる
・relwidthの値に100÷5の値を入れる = 20%の領域が生成される
・そこから、余白の大きさ分を引き算する「100÷5 - 2」 → 2%の余白が生成される
・relxの値も「/100」で設定
・relxの位置は×100÷0~nの値で設定できる
・余白を作った場合は、relxに余白の大きさ÷2の値を足し算する
・これで、周囲に2%の余白ができる
//ーーーーー
【計算式の表示】
・relwhith = (1÷100)×(100÷"分割数") - "余白サイズ"
・relx = (1÷100)×(100÷"分割数")× "0~の位置" + ("余白サイズ"÷2)
↓(簡略化)
・relwhith = ("分割数" - "余白サイズ" ) ÷100
・relx = (("分割数"×"0~の位置")+ ("余白サイズ"÷2)) ÷100
こちらを入力。

すると、周囲に2%の余白を生成した状態で5等分できます。


慣れると、これが便利すぎるので、ほぼコレしか使わなくなります。
また、もちろん「relheight」や「rely」といった高さ方向の処理でも同じことが可能です。
ここではLabel_6を追加し、relheight「20/100」で20%の高さになるように設定。
位置は8%の位置に設定。


横は大きさ90%(relwidth)
位置は5%の位置です。(relx)
…みたいな形で、UIを作り込むことができます。

色々試したところ…
これが一番、レスポンシブデザインを綺麗にかつ、簡単で思い通りに作れたので…
UI制作は「.place()」と「rel」系処理を組み合わせて「/100」して作る事をおすすめします。
まとめ
今回は、Pythonのtkinterモジュールで.place()を使ったウィジットの配置方法を紹介しました
・.place()はウィジットの横位置をx、縦位置をyで指定して配置する
・領域の幅はwidth、高さはheightで設定可能
・ウィジットが重なった場合は、処理順で重なる
・relx/yやrelwidth/heightを使うと、画面の大きさに合わせて位置や大きさを変更可能
・rel系処理に「÷100」を入れるとUI要素を1%単位で設定できる
・細かく作り込むなら「rel系処理」+「÷100」を組み合わせるのがおすすめ
また、他にもPythonやプログラムについて解説してます。



ぜひ、こちらもご覧ください。
コメント