LoginSignup
7
5

More than 3 years have passed since last update.

kivyを使ってGUIプログラミング ~その6 レイアウトいろいろ~

Last updated at Posted at 2020-07-02

はじめに

その4でボタンの説明をしましたが、レイアウトに関しても複数存在するためいろいろ紹介してみたいと思います。
前回と同様に簡単な説明と、例を示して行きます、詳しい説明はリファレンスを見ていただけたらと思います。

レイアウト

リファレンスのレイアウト一覧にある順番で紹介していきます。

AnchorLayout

kivy.uix.anchorlayout

配置するオブジェクトを画面の上、真ん中等簡単に配置が行えるレイアウトです。
配置場所の指定は、anchor_xanchor_yという変数に対して
anchor_xならleft, center, right
anchor_yならtop, center, bottomの組み合わせ計9箇所から指定できます。
また、1つのAnchorLayoutに対して1つしかwidgetを追加できないので注意する必要があります。複数配置したい場合は、AnchorLayoutに別のレイアウトを追加すれば良いと思います。

import random

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button


class Test(AnchorLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)

        self.x_positon = ["left", "center", "right"]
        self.y_positon = ["top", "center", "bottom"]
        self.anchor_x = "center"
        self.anchor_y = "center"

        btn = Button(text='Hello World', size_hint=(0.5,0.5), on_press=self.click)
        self.add_widget(btn)

    def click(self,btn):
        x = random.choice(self.x_positon)
        y = random.choice(self.y_positon)
        self.anchor_x = x
        self.anchor_y = y
        btn.text = "x : {}\ny : {}".format(x, y)


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

sample1.gif

BoxLayout

kivy.uix.boxlayout

ウィジェットを水平方向か垂直方向に並べるように配置するレイアウトです。
デフォルトでは、水平方向にウィジェットが追加されていきます。方向を変更するには、orientationという変数に垂直方向にしたいならvertical、水平方向に配置したいならhorizontalを代入することで向きを変えることができます。途中でウィジェットの追加向きを変えるということはできないと思うので、新しいBoxLayoutをadd_wigetして配置を変える感じになるかと思います。

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


class Test(BoxLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)

        self.count = 0
        #デフォルトは"horizontal"水平方向に配置されます。
        self.orientation = "horizontal"
        #self.orientation = "vertical"

        btn = Button(text='Hello World', on_press=self.click)
        self.add_widget(btn)

    def click(self,btn):
        self.count += 1
        self.add_widget(Button(text="{}".format(self.count),on_press=self.dismiss))

    def dismiss(self, a):
        self.remove_widget(a)


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

sample2.gif

FloatLayout

kivy.uix.floatlayout

FloatLayoutは上で紹介したようなレイアウトとは異なり、絶対位置を指定して配置することができます。
絶対位置であるため、widget配置後にウィンドウの大きさを変えたりしてもオブジェクトはウィンドウに合わせて位置が変化することはないため注意する必要があります。

import random

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button

class Test(FloatLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)

        btn = Button(text='Hello World', size_hint=(0.1,0.1), on_press=self.click)
        self.add_widget(btn)

    def click(self,btn):
        x = int(random.uniform(0,self.width))
        y = int(random.uniform(0,self.height))
        self.add_widget(Button(text="x : {}\ny : {}".format(x, y), pos=(x,y), size_hint=(0.1,0.1)))


class Sample(App):
    def build(self):
        return Test()

if __name__ == '__main__':
    Sample().run()

sample3.gif

RelativeLayout

kivy.uix.relativelayout

使い方がイマイチわかりませんでした。
わかり次第記事を更新したいと思います。

GridLayout

kivy.uix.gridlayout

GridLayoutはグリッドとあるように表計算みたいな形でウィジェットを追加していく配置になります。
配置はcolsrowsから指定することができます。colsに数値を代入すると、その数値分だけ横に配置が終わるとその下に新しい段を作りさらに追加していきます。rowsは縦方向の最大値を指定して、横方向にウィジェットを追加していきますが、イマイチ挙動がよくわかりませんでした。同時にcolsrowsを用いると、cols×rowsのグリッドを作成することができます。

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button


class Test(GridLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)
        self.count = 0
        btn = Button(text='Hello World', on_press=self.click)
        self.cols = 5
        #self.rows = 5

        self.add_widget(btn)

    def click(self,btn):
        self.count += 1
        self.add_widget(Button(text="{}".format(self.count)))


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

sample4.gif

PageLayout

kivy.uix.pagelayout

PageLayoutは、画面に別の画面を配置できるようなレイアウトになっており、簡単な画面遷移のようなことができると思います。画面端の線(見辛いですが,,)をクリックしながら横にドラッグすると別の画面が出てきます(ちょっと操作しづらいですw)。例ではボタンをそのまま貼り付けていますが、本来はPageLayoutに別のレイアウトをadd_widgetをするような使い方になると思います。

from kivy.app import App
from kivy.uix.pagelayout import PageLayout
from kivy.uix.button import Button


class Test(PageLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)
        btn1 = Button(text='Hello World1', size_hint=(0.5, 0.5))
        self.add_widget(btn1)

        btn2 = Button(text='Hello World2', size_hint=(0.5, 0.5))
        self.add_widget(btn2)

        btn3 = Button(text='Hello World3', size_hint=(0.5, 0.5))
        self.add_widget(btn3)


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

sample5.gif

ScatterLayout

kivy.uix.scatterlayout

ScatterLayoutは、マウスで位置を変えたり、大きさを変えることができたりするレイアウトです。例では、ラベルを2つ貼ったBoxLayoutをScatterLayout上で動かしてみています(ラベルだけだと見辛かったので破線を追加しています)。本来なら画像アプリなどで画面を拡大したりとかそういった使い方をすると思います。パソコンよりスマホアプリような気がします。

from kivy.app import App
from kivy.uix.scatterlayout import ScatterLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.config import Config
#破線を表示する
Config.set('modules', 'ShowBorder', '')


class Test(ScatterLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)

        layout = BoxLayout()

        label = Label(text="Hello World!")
        layout.add_widget(label)

        label2 = Label(text="Hello World!")
        layout.add_widget(label2)

        self.add_widget(layout)


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

sample6.gif

StackLayout

kivy.uix.stacklayout

StackLayoutは、BoxLayoutと同じように配置する方向を指定するようなレイアウトになっています。
BoxLayoutと違いは、並べる向きを8つのパラメータから指定できることと、画面外に出そうになると、
次の段や横などに配置を変更する点です。並べる方向ですが、orientationという変数から指定することができ、lrtbというパラメータを組み合わせたもので向きを指定します。例で書いてあるlr-tbですがlrは左(left)から右(right)、tbは上(Top)から下(Bottom)であり、左から右方向に配置し、画面端にいったら上から下にウィジェットを追加するとなります。

from kivy.app import App
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button


class Test(StackLayout):
    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)

        ori = ["lr-tb","tb-lr","rl-tb","tb-rl","lr-bt","bt-lr","rl-bt","bt-rl"]

        # デフォルトでは右方向、上から下方向に進みます。
        self.orientation="lr-tb"

        for i in range(100):
            btn = Button(text=str(i), width=40 + i * 5, size_hint=(None, 0.15))
            self.add_widget(btn)


class Sample(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    Sample().run()

 lr-tbを指定すると左の画像、bt-rlを指定すると右の画像のようになります。
画像.png

まとめ

普段はboxlayoutを使うことが多いため、その他のレイアウトについてほぼ知識がない状態でしたので良い機会となりました。結局調べたもののrelativelayoutについてはイマイチ使い方がわからなかったのでもう一度調べてみたいと思いました。

参考サイト

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5