#はじめに
その4でボタンの説明をしましたが、レイアウトに関しても複数存在するためいろいろ紹介してみたいと思います。
前回と同様に簡単な説明と、例を示して行きます、詳しい説明はリファレンスを見ていただけたらと思います。
#レイアウト
リファレンスのレイアウト一覧にある順番で紹介していきます。
###AnchorLayout
kivy.uix.anchorlayout
配置するオブジェクトを画面の上、真ん中等簡単に配置が行えるレイアウトです。
配置場所の指定は、anchor_x
、anchor_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()
###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()
###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()
kivy.uix.relativelayout
使い方がイマイチわかりませんでした。
わかり次第記事を更新したいと思います。
###GridLayout
kivy.uix.gridlayout
GridLayoutはグリッドとあるように表計算みたいな形でウィジェットを追加していく配置になります。
配置はcols
とrows
から指定することができます。cols
に数値を代入すると、その数値分だけ横に配置が終わるとその下に新しい段を作りさらに追加していきます。rows
は縦方向の最大値を指定して、横方向にウィジェットを追加していきますが、イマイチ挙動がよくわかりませんでした。同時にcols
とrows
を用いると、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()
###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()
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()
###StackLayout
kivy.uix.stacklayout
StackLayoutは、BoxLayoutと同じように配置する方向を指定するようなレイアウトになっています。
BoxLayoutと違いは、並べる向きを8つのパラメータから指定できることと、画面外に出そうになると、
次の段や横などに配置を変更する点です。並べる方向ですが、orientation
という変数から指定することができ、lr
やtb
というパラメータを組み合わせたもので向きを指定します。例で書いてある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
を指定すると右の画像のようになります。
#まとめ
普段はboxlayoutを使うことが多いため、その他のレイアウトについてほぼ知識がない状態でしたので良い機会となりました。結局調べたもののrelativelayoutについてはイマイチ使い方がわからなかったのでもう一度調べてみたいと思いました。
#参考サイト