Python+Kivy入門

Kivyのレイアウト:BoxLayoutの使い方【kv言語】

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

Kivyの基本的なレイアウトであるBoxLayoutの使い方について説明します。

BoxLayoutとは

レイアウトはコンテナのようなもので、BoxLayoutは垂直方向(縦)または水平方向(横)にUIウィジェットを並べて配置します。方向のプロパティを指定しなかった場合は水平方向になります。

Kivyアプリの基本構成

BoxLayoutはウィジェットを整列させるためのレイアウトなのでウィジェットを自由な位置に配置することはできません。そのため、ウィジェットの位置を設定するpos_hintなどのプロパティは機能しませんので注意して下さい。自由にウィジェットを配置したい場合はFloatLayoutやRelativeLayoutなどの他のレイアウト方が適しています。

BoxLayoutを定義する位置

ウィジェットは並べたい順番に記述していくので、BoxLayoutはルートウィジェットになるか通常ウィジェット定義の中で一番上になります。

#クラスルールを指定した場合はウィジェット定義の一番上
<RootWidget>:
    BoxLayout:
#ルートルールにした場合
BoxLayout:

ルールについての詳細は下記の記事をご覧ください。

UIウィジェットの配置

BoxLayoutを定義したら、子要素にBoxLayoutの設定を決めるプロパティを定義します。UIウィジェットはBoxLayoutの子要素として並べたい順番に記述していきます。更にUIウィジェットの子要素としてプロパティを定義していきます。

ツリー構成で見るとBoxLayoutのプロパティと同じ位置になります。

<RootWidget>
 ∟BoxLayout
    ∟プロパティ
   ∟Label
      ∟プロパティ
   ∟Button
      ∟プロパティ

インデントでツリー構成を表しているのでインデントの数を間違えるとエラーになるので気をつけてください。

<RootWidget>:
    BoxLayout:
      orientation: 'vertical'
        Label:
            text: ''
        Button
            text: ''

ウィジェットのプロパティはデフォルト値が設定されているので変更したい場合だけ定義します。

ウィジェットを配置する方向を設定する

ウィジェットを配置する方向を設定するにはorientationプロパティにvertical(垂直)かhorizontal(水平)を指定します。水平方向にしたい場合はデフォルト値なので定義しなくても問題ありません。

BoxLayout:
    orientation: 'horizontal'
BoxLayout:
    orientation: 'vertical'

内側の余白(padding)を設定する

レイアウト内とウィジェットの間の余白を設定するにはpaddingプロパティ定義します。

Kivyレイアウトのpadding
  • padding_left:左側の余白
  • padding_top:上側の余白
  • padding_right:右側の余白
  • padding_bottom:下側の余白

デフォルトは全ての方向で0になります。つまり画面領域は余白なしでウィジェットで埋め尽くされます。

画面領域の大きさを超えた数値を設定しても画面上から消えるだけでエラーにはならないので気を付けてください。例えば500x500の画面サイズの場合paddingに1000を設定しても特にエラーにはなりません。

paddingプロパティは3つの書き方があります。数値の単位はピクセルです。

padding書き方➀

[0,0,0,0]で指定します。(左、上、右、下)になります。

padding: 50, 100, 50, 100

padding書き方②

水平方向の余白と垂直方向の余白を指定します。

padding: 50,100

padding書き方➂

全ての方向をまとめて指定します。全て同じ余白を設定する場合はこちらをお勧めします。

padding: 100

ウィジェット間の余白を設定する

ウィジェットとウィジェットの間の余白を設定するにはspacingプロパティを定義します。単位はピクセルになります。

kivyレイアウトのspacing
spacing: 20

サンプルコード

実際にpaddingとspacingプロパティの値を変えて試してみてください。余白に合わせてウィジェットを自動で調整していてレスポンシブ対応されていることを確認してください。

boxlayout1.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class RootWidget(BoxLayout):  
    pass

class BoxLayout1(App):
    def build(self):
        return RootWidget()

if __name__ == "__main__":
    BoxLayout1().run()

boxlayout1.kv

<RootWidget>:
    orientation: 'vertical'
    #padding: 20000, 10, 10, 10 #画面から消える例
    #padding: 300, 300
    padding: 100
    spacing: 100

    Button:
        text: 'Button'
    
    Button:
        text: 'Button'

BoxLayoutを入れ子にする

レイアウトは入れ子にすることも可能です。ただし、複数の入れ子は重くなる可能性があります。またidのスコープなどの関係で意図しない挙動になる可能性もあります。kivyにはGridLayoutなど他のレイアウトも用意されているのでそちらも検討してください。

サンプルコード

下記のツリー構成になります。縦に3つ並んだセルがあり、真ん中のセルがBoxLayoutが入れ子されて横並びになっています。

<RootWidget>
 ∟BoxLayout
   ∟Button
   ∟BoxLayout
     ∟Button
     ∟Button
   ∟Button

boxlayout2.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

class RootWidget(BoxLayout):  
    pass

class BoxLayout2(App):
    def build(self):
        return RootWidget()

if __name__ == "__main__":
    BoxLayout2().run()

boxlayout2.kv

<RootWidget>:
    orientation: 'vertical'
    padding: 100
    spacing: 100

    Button:
        text: 'Button'
    
    BoxLayout:
        orientation: 'horizontal'
        #padding: 100
        #spacing: 50
    
        Button:
            text: 'Button'
    
        Button:
            text: 'Button'

    Button:
        text: 'Button'

ウィジェットが機能しなくなる設定例

paddingやspacingの設定によってはウィジェットが機能しなくなる場合があります。上記のサンプルコードのコメントを外してみてください。

        #padding: 100
        #spacing: 50

下図の赤丸部分のように「ー」が表示されてボタンとして機能していません。これは画面を最大にすると直りますが、デフォルトの画面サイズではKivyで自動調整した結果、余白幅が大きすぎる事を示しています。

レイアウトプロパティでウィジェットが機能しなくなる例

レイアウトの背景色を設定するには

レイアウトの背景色を変えるのはbackgroundのようなプロパティがないのでちょっと面倒です。詳細は別の記事にしましたので下記をご覧ください。

ウィジェットのサイズを変更するには

ウィジェットのサイズはsize_hintを使用します。詳細は別の記事にしましたので下記をご覧ください。


Comment

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