Kivyアプリでウィジェットの位置を設定するposかpos_hintの使い方を解説します。これらは一部のレイアウトウィジェットでの使用に限られます。また、親や子の位置を取得する方法も解説します。
ウィジェットの位置を設定する
ウィジェットの位置を設定するにはposかpos_hintを使用します。これらのプロパティは一部のレイアウトウィジェットに使うことができます。
- BoxLayout(正確に機能しない場合がある)
- GridLayout
- Float Layout
- RelativeLayout
- ScatterLayout
posまたはpos_hintプロパティはウィジェットに設定します。
pos_hintプロパティ
pos_hintプロパティは親に対して相対的にウィジェットを配置します。親はレイアウト、Appクラス、Widgetクラス、Windowクラスなどになります。位置の指定には3つの方法があります。
- x軸とy軸で指定する
- center_xとcenter_yで指定する
- rightとtopで指定する
pos_hintをx軸とy軸で指定する
x軸(水平方向)とy軸(垂直方向)でウィジェットの位置を指定します。Kivyの場合、画面左下がx=0,y=0になります。値は0~1の間の数値で指定し、0.5なら50%になります。
レイアウトの内側の余白を設定するpaddingやウィジェット間のスペースを設定するspacingが設定されていた場合はその値を除外して計算されます。
例えばx=0.3、y=0.6の場合、x軸には左から30%の位置に、y軸には下から60%の位置にウィジェットが配置されます。
pos_hint {'x': 0.5, 'y': 0.5}
上記のようにx=0.5、y=0.5にした場合、画面の中心にウィジェットが置かれる訳ではありません。これはウィジェットのベース位置を基準にして配置されるためです。3つの方法それぞれでベース位置が異なっており、x軸とy軸で指定した場合、ウィジェットの左下の角を基準に配置されます。つまり、左から50%、下から50%の位置にウィジェットの左下の角が配置されます。そのため、ウィジェットの位置は画面の中心ではなく、中心からずれて表示されます。これを真ん中に配置するにはcenter_xとcenter_yで指定します。

pos_hintをcenter_xとcenter_yで指定する
center_xとcenter_yも同じように0~1の間の数値で指定します。これのベース位置はウィジェットの中心点になります。例えばx=0.1、y=0.3の場合、x軸には左から10%の位置に、y軸には下から30%の位置に、ウィジェットの中心点が配置されます。x=0.5、y=0.5で画面の中心にウィジェットが配置されます。
pos_hint: {'center_x': 0.5, 'center_y': 0.5}

pos_hintをrightとtopで指定する
rightとtopで指定することもできます。これのベース位置はウィジェットの右上の角になります。
pos_hint: {'right': 0.5, 'top': 0.5}

ウィジェットのベース位置まとめ
キーを混在できる
キー[x , y]と[right , top]を混在させて記述することも可能です。
# 左上の角に配置
pos_hint={'x': 0, 'top': 1}
# 右下の角に配置
pos_hint={'right': 1, 'y': 0}
# center_xとyの混在で指定
pos_hint: {'center_x': 0.5}
y: 100
posプロパティ
posプロパティはx軸とy軸を座標で指定します。
pos: 300, 500
画面からはみ出るウィジェット
画面サイズの境界を超えた位置にウィジェットを配置した場合、ウィジェット画面からはみ出して表示されます。エラーはスローされないので注意してください。

サンプルコード
pos_hint1.py
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
class RootWidget(RelativeLayout):
pass
class PosHint1(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
PosHint1().run()
poshint1.kv
<RootWidget>:
padding: 20
#spacing: 20
Button:
text: 'Button 1'
size_hint: 0.3, 0.2
#pos_hint: {'x': 0.2, 'y': 0.9} # これはウィジェットがはみ出る。
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
#pos_hint: {'right': 0.5, 'top': 0.5}
#pos_hint: {'x': 0, 'top': 1}
#pos: 300, 500
#pos_hint: {'center_x': 0.5}
#y: 100
ウィジェットの位置を取得する
ウィジェットの位置を取得する方法をいくつか紹介します。他のウィジェットの位置を基準にして計算したい場合などに便利です。
ウィジェットの[ x , y ]位置の取得は原点(左下角)が返されます。親の[ x , y ]は[ 0 , 0 ]が返され、子の[ x , y ]はウィジェットの左下角の位置になります。
ウィジェットの[ center-x , center-x ]の位置を取得する場合は、そのウィジェットの中心の位置が返されます。
kvコードで自身のウィジェットの位置を取得する
kvコードで自身のウィジェットを取得するにはselfキーワードを使います。通常は引数で渡したり、自身のサイズをtextに表示するなどで使います。
Button:
pos_hint: 1, 0
text: str(self.pos)
on_press: callback_function(self.pos)
kvコードで他のウィジェットの位置を取得する
kvコードで他のウィジェットの位置を取得するにはidを使用します。
Button:
id: button
text: 'text'
pos_hint: {'center_x': 0.5, 'y': 0.9}
size: 100,50
Label:
text: 'text'
pos_hint: {'center_x': 0.5}
y: int(button.y - 140)
上記ではButtonのidで縦の位置を取得しています。x軸に0.5(中央)を指定し、y軸はButtonの位置を基準にし、その値から140を引いています。button.yを取得するとflot型で返ってくるのでint型に変換しています。
kvコードで親の位置を取得する
kvコードで親の位置を取得するにはparentキーワードを使います。
Button:
on_press:
print(f"Parent pos-x: {self.parent.x} pos-y: {self.parent.y}")
print(f"Parent.pos: {self.parent.pos}")
これを取得すると親の原点(左下角)である[0, 0]が返されます。
Pythonコードでchildウィジェットの位置を取得する
ルートウィジェットは親になるので、そのツリーに構成されているウィジェットは子になります。子ウィジェットはchildrenのリストで一括で取得することが可能です。
for child in self.children:
print(f"Child {child.text} size: {child.size}, pos: {child.pos}")
childrenは下記のようなリストになっているのでfor文で展開します。オブジェクトを代入した一時変数を使って、ウィジェットのプロパティを取得できます。
[<kivy.uix.label.Label object at 0x000002A2F9CB9400>, <kivy.uix.label.Label object at 0x000002A2EED82C80>, <kivy.uix.label.Label object at 0x000002A2EED80590>, <kivy.uix.label.Label object at 0x000002A2EED6DE10>, <kivy.uix.label.Label object at 0x000002A2EED63690>, <kivy.uix.label.Label object at 0x000002A2EED61080>, <kivy.uix.button.Button object at 0x000002A2EED3E040>]
個別に子ウィジェットの位置を取得したい場合は、idsの名前空間で取得します。
print(f"Child size: {self.ids.button.size}, pos: {self.ids.button.pos}")
Pythonコードで親の位置を取得する
ルートウィジェットは親であり、自身を指すのでselfキーワードを使用します。
print(f"Parent size: {self.size}, pos: {self.pos}")
これを取得すると親の原点(左下角)である[0, 0]が返されます。
これらの例を使用したサンプルコードを下記の記事で紹介しています。
Comment