LoginSignup
9
6

More than 5 years have passed since last update.

Kivy ScrollViewの基本

Last updated at Posted at 2018-10-26

ScrollView

scrollのコピー.gif

main.py
from kivy.app import App

class MainApp(App):
    pass

if __name__ == "__main__":
    MainApp().run()
main.kv
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の子とするだけです。
しかし、ただ子にするだけではスクロールできる状態にならず以下の様ないくつかの指定をする必要があります

.kv
        size_hint_y: None
        row_default_height: 200
        height: self.minimum_height

何故これが必要なのか、何故これで実現されるのかを見ていきたいと思います

基本的な考え方

ScrollViewによってスクロール可能な状態にする為には、
子Widgetのheight/widthいずれかを下図の様に親Widgetのheight/widthより大きくする必要があります。

スクリーンショット 2018-10-28 19.44.30.png

これを実現する為の条件は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のサイズを自動調整するためのものであるという前提があります(下図参照)

↓size_hint_y: 1 (default)
スクリーンショット 2018-10-26 23.07.35.png

↓size_hint_y: 0.5
スクリーンショット 2018-10-26 23.06.28.png

↓size_hint_y:4
スクリーンショット 2018-10-26 23.04.00.png

従って,これを1より大きくすることでスクロールを実現する条件①、②を満たします
1以下では条件①を満たさずスクロール可能にはなりません

方法1を具体的に示すと以下の様な構造が考えられます

main.kv
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です

↓size_hint: None, Noneの状態
スクリーンショット 2018-10-26 23.55.22.png

具体的には以下の様な構成が考えられます

main.kv
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のサイズの合計が画面サイズを超えていてもスクロール可能にはなりません

また、

.kv
height: self.minimum_height
width: self.minimum_width

という指定をすることでLayoutのサイズが子ウィジットが全て収まる最小のサイズになるように設定されます
ここを任意の数字にしてしまうと、row_defaultやcol_defaultより優先されてしまい意図したウィジットサイズにならないので注意が必要です

その他の例

BoxLayout

名称未設定.gif

main.kv
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

main.kv
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
9
6
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
9
6