ScrollView
from kivy.app import App
class MainApp(App):
pass
if __name__ == "__main__":
MainApp().run()
ScrollView:
GridLayout:
cols:2
size_hint_y: None
row_default_height: 200
height: self.minimum_height
Button:
text: "1"
Button:
text: "2"
Button:
text: "3"
Button:
text: "4"
Button:
text: "5"
Button:
text: "6"
Button:
text: "7"
Button:
text: "8"
Button:
text: "9"
Button:
text: "10"
Button:
text: "11"
Button:
text: "12"
上の例はこのようなコードで実現できます
見て分かる通りScrollViewの子WidgetであるGridLayoutがスクロール可能になっています。
この様にスクロールを実現するにはスクロール可能にしたいWidgetをScrollViewの子とするだけです。
しかし、ただ子にするだけではスクロールできる状態にならず以下の様ないくつかの指定をする必要があります
size_hint_y: None
row_default_height: 200
height: self.minimum_height
何故これが必要なのか、何故これで実現されるのかを見ていきたいと思います
基本的な考え方
ScrollViewによってスクロール可能な状態にする為には、
子Widgetのheight/widthいずれかを下図の様に親Widgetのheight/widthより大きくする必要があります。
これを実現する為の条件は2つだけで上の例ではそれを満たしています。
スクロール可能条件
①子Widgetが親Widget内に収まらない状態を可能する
②子Widgetのheght/widthを親Widgetのheight/widthより大きくする
これらが具体的にどのように実現されるのかを見てみます
実際の方法
上の2つの条件を満たす為には以下の方法が考えられます(他の方法もあるかもしれません)
方法1. 子Widgetのsize_hintの値を1より大きくする
方法2. 子Widgetのsize_hintの値をNoneにして、子Widgetのheightを調整する
以下、親WidgetがScrollView(rootかつsize_hint:default),子WidgetがGridLayoutの場合の例を考えます
方法1 : 子Widgetのsize_hintを1より大きくする
まず子Widgetのsize_hintの値というのは
それ自身もしくはそれ自身の全ての子Widgetが(親Widgetのwidth×size_hint_x)×(親Widgetのheight×size_hint_y)に収まるようにLayoutのサイズを自動調整するためのものであるという前提があります(下図参照)
従って,これを1より大きくすることでスクロールを実現する条件①、②を満たします
1以下では条件①を満たさずスクロール可能にはなりません
方法1を具体的に示すと以下の様な構造が考えられます
ScrollView:
GridLayout:
cols:2
size_hint_x: 3 #任意の1より大きい値
size_hint_y: 2 #任意の1より大きい値
#以下任意のWidget
この場合Layoutとその中のWidgetのサイズが画面サイズによって可変的に決められ自分で設定することが出来ないのが特徴です
一方,方法2では子Widgetのサイズを固定することができます
方法2 : 子Widgetのsize_hintの値をNoneにして、そのheightを調整する
Widgetのsize_hintをNoneにするとWidgetは指定されたheight/widthに固定されます。(GridLayoutの場合defaultではheight/weightともに100)
これを利用して、子Widgetのheight/widthを画面サイズ以上の値を指定することで条件①、②を満たしスクロール可能にするのが方法2です
具体的には以下の様な構成が考えられます
ScrollView:
GridLayout:
cols:2
size_hint_y: None #スクロール可能条件①を満たす
row_default_height: 200 #rowのheightを指定
height: self.minimum_height
#(画面サイズ<self.minimum_heightの場合)スクロール可能条件②を満たす
#以下任意のWidget
size_hintがNoneになっていない、またはLayoutのheightが画面サイズ以上に指定されていない場合は条件を満たさずスクロール可能にはならないので注意が必要です。
たとえLayout内のWidgetのサイズの合計が画面サイズを超えていてもスクロール可能にはなりません
また、
height: self.minimum_height
width: self.minimum_width
という指定をすることでLayoutのサイズが子ウィジットが全て収まる最小のサイズになるように設定されます
ここを任意の数字にしてしまうと、row_defaultやcol_defaultより優先されてしまい意図したウィジットサイズにならないので注意が必要です
その他の例
BoxLayout
ScrollView:
BoxLayout:
size_hint_y: None
orientation: "vertical"
height: self.minimum_height
Label:
size_hint_y: None
text: "1"
height: 500
Button:
size_hint_y: None
text: "2"
Label:
size_hint_y: None
text: "3"
ToggleButton:
size_hint_y: None
text: "4"
Label
ScrollView:
Label:
size_hint: None, None
text: "testtesttest"
size: 2000,2000
font_size: 300
canvas.before:
Color:
rgba: 0.9,0,0.3,1
Rectangle:
size: self.size
pos: self.pos