LoginSignup
4
4

More than 3 years have passed since last update.

Layoutことはじめ

Last updated at Posted at 2018-11-04

Kivyを始めて一番最初にぶち当たった壁はなんですか?私は間違いなくwidgetの配置です。何故かwidgetの位置や大きさが思い通りになってくれないのです。例えば以下のcodeを見てください。

from kivy.app import runTouchApp
from kivy.factory import Factory

root = Factory.FloatLayout()
root.add_widget(Factory.Button(size=(100, 100), text='Push Me'))
runTouchApp(root)

私は以下のように画面左下にsizeが100x100のButtonが出る事を期待していたのですが

20_00.png

実際は

20_01.png

という風にWindow全体にButtonが広がってしまいました。inspectorで調べてみると

20_02.png

sizeが800x600になっている事が確認できます。何故でしょうか?原因はsize_hintの事を考えてなかったからです。

位置や大きさに関するproperty

全てのwidgetが共通して持っているpropertyの内、位置や大きさに関する物が以下です。

非hint系 hint系
位置 pos x y right top center center_x center_y pos_hint
大きさ size width height size_hint size_hint_x size_hint_y size_hint_min size_hint_min_x size_hint_min_y size_hint_max size_hint_max_x size_hint_max_y

たくさんあってややこしいですが、幾つかのpropertyは単に複数のpropertyをlistの形で扱えるように(まと)めただけなのでそれらの重複を除くと以下のように見やすくできます。

非hint系 hint系
位置 pos right top center pos_hint
大きさ size size_hint size_hint_min size_hint_max

pos[0] == x, pos[1] == y, size[0] == width, size_hint[1] == size_hint_y, size_hint_min[0] == size_hint_min_x といった具合の対応関係です。

上の表ではpropertyを非hint系hint系の二つに分類していますが、これがどういう分類なのかと言うと

非hint系は特に難しいことはなく只の位置や大きさを表す数値で単位はpixelです。hint系はややこしくなっていて、まず hint系のpropertyは、その持ち主の親次第で意味が変わります。 冒頭の失敗例で言うなら

  • Buttonの親はFloatLayoutなので、Buttonの持つhint系のpropertyの意味はFloatLayoutの流儀に従う
  • FloatLayoutも実は親にWindowを持っているので、FloatLayoutの持つhint系のpropertyの意味はWindowの流儀に従う

ということです。次に hint系のpropertyには有効な状態と無効な状態があり、ほとんどのwidgetは既定でsize_hint(size_hint_x, size_hint_y)のみが有効になっています。 具体的にはそれぞれ

  • pos_hintは既定値が空の辞書で、無効 な状態です。そして{'x': 0, 'right': .5}のように非hint系の位置を表すpropertyの名前をkeyにして数値が入っている状態が 有効 です。
  • size_hint_xsize_hint_yは既定値が1で、 数値が入っている状態が 有効 です。Noneだと 無効
  • size_hint_min_x, size_hint_min_y, size_hint_max_x, size_hint_max_y は既定値がNoneで、 無効 な状態です。数値が入っていると 有効

となっています。この size_hintが既定で有効になっている事 がKivyにおいて最初に気を付けるべき所で、これによって親のwidget次第で既にsize(width, height)による大きさの指定ができなくなっています。(冒頭の失敗例がそれ)。

最初に学ぶべきこと

というわけで最初に学ぶべきは、各種Layoutが子widgetのhint系propertyをどのように扱うかを知ることだと思います。まずはFloatLayoutBoxLayoutからお薦めします。

冒頭の失敗例の修正

気付いているかもしれませんが、冒頭の失敗例はsize_hintを無効にする事で期待通りの結果を得られます。

from kivy.app import runTouchApp
from kivy.factory import Factory


root = Factory.FloatLayout()
root.add_widget(Factory.Button(size=(100, 100), text='Push Me', size_hint=(None, None)))
runTouchApp(root)

20_00.png

4
4
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
4
4