PR
Python+Kivy入門

Kivyのpos_hintの使い方。ウィジェットの位置を設定・取得する【kv言語】

この記事は約8分で読めます。

Kivyアプリでウィジェットの位置を設定するposかpos_hintの使い方を解説します。これらは一部のレイアウトウィジェットでの使用に限られます。また、親や子の位置を取得する方法も解説します。

ウィジェットの位置を設定する

ウィジェットの位置を設定するにはpospos_hintを使用します。これらのプロパティは一部のレイアウトウィジェットに使うことができます。

  • BoxLayout(正確に機能しない場合がある)
  • GridLayout
  • Float Layout
  • RelativeLayout
  • ScatterLayout

posまたはpos_hintプロパティはウィジェットに設定します。

pos_hintプロパティ

pos_hintプロパティは親に対して相対的にウィジェットを配置します。親はレイアウト、Appクラス、Widgetクラス、Windowクラスなどになります。位置の指定には3つの方法があります。

  1. x軸とy軸で指定する
  2. center_xcenter_yで指定する
  3. righttopで指定する

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_xcenter_yで指定します。

Kivyのpos_hintのcenter位置

pos_hintをcenter_xとcenter_yで指定する

center_xcenter_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}
Kivyのpos_hintのx軸とy軸

pos_hintをrightとtopで指定する

righttopで指定することもできます。これのベース位置はウィジェットの右上の角になります。

pos_hint: {'right': 0.5, 'top': 0.5}
Kivyのpos_hintのrightとtop

ウィジェットのベース位置まとめ

  • center_xとcenter_y: ウィジェットの中心を基準に配置
  • xとy: ウィジェットの左下の角を基準に配置
  • rightとtop: ウィジェットの右上の角を基準に配置

キーを混在できる

キー[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 

画面からはみ出るウィジェット

画面サイズの境界を超えた位置にウィジェットを配置した場合、ウィジェット画面からはみ出して表示されます。エラーはスローされないので注意してください。

Kivyのpos_hint。画面からはみ出したウィジェットの例

サンプルコード

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

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