前回、RecycleViewがよくわからん、と愚痴ったわけですが、あれはどうも、リファレンス(https://kivy.org/docs/api-kivy.uix.recycleview.html)がそのRecycleViewの概略に行きすぎて、実際の書き方についてわかりづらい、と言う結論に達しました。

その後いろんなソースを目にして、一番参考になったのは、ここ(https://github.com/kivy/kivy/blob/master/examples/widgets/recycleview/basic_data.py)。そして、前回でも登場した「(kivy)RecycleViewに組み込んだCheckBoxの状態の取得方法について https://teratail.com/questions/111242)」が参考になりまして、自分なりに考えたのがこのソースになります。

 

kv18-2a.py


from random import sample
from string import ascii_lowercase

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout

from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path

# 日本語フォント設定
resource_add_path('./fonts')
LabelBase.register(DEFAULT_FONT, 'ipaexg.ttf')


kv = """
<VariousButtons>:
    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Button:
        text: root.value
        background_normal: ''
        background_color: 0.5, 0.5, 0.75, 1
        color: 1, 1 ,1 ,1
        on_press: root.on_select_button(self)
<Test>:
    canvas:
        Color:
            rgba: 0.3, 0.3, 0.3, 1
        Rectangle:
            size: self.size
            pos: self.pos
    rv: rv
    RecycleView:
        id: rv
        scroll_type: ['bars', 'content']
        scroll_wheel_distance: sp(60) #スクロール速度
        bar_width: sp(20)
        viewclass: 'VariousButtons'
        RecycleBoxLayout:
            default_size: None, sp(160)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(8)
"""

Builder.load_string(kv)


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

        self.rv.data = []
        btn_list = ['ひつまぶし','味噌煮込みうどん','味噌カツ','台湾ラーメン' \
                    ,'手羽先','小倉トースト','きしめん','あんかけスパ','どて煮' \
                    ,'ういろう','甘口バナナスパ']
        for btn_list_any in btn_list:
            self.rv.data.append({'value': btn_list_any})



class VariousButtons(BoxLayout):
    def on_select_button(self, button):
        print('press:'+button.text)


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


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

これを実行すると、

となり、各ボタンを押下すると、

 

と、表示される。

 

RecycleViewのリストの中に、ボタンを入れる構成。

 

まず、RecycleViewの作成。<Test>

kv18-2a.py抜粋 (kvファイル部分)


<Test>:
    canvas:
        Color:
            rgba: 0.3, 0.3, 0.3, 1
        Rectangle:
            size: self.size
            pos: self.pos
    rv: rv
    RecycleView:
        id: rv
        scroll_type: ['bars', 'content']
        scroll_wheel_distance: sp(60) #スクロール速度
        bar_width: sp(20)
        viewclass: 'VariousButtons'
        RecycleBoxLayout:
            default_size: None, sp(160)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(8)

重要なのは赤字で示した部分。


    rv: rv
    RecycleView:
        id: rv

で、RecycleViewの宣言と、pythonコード側で使うrvの宣言。


        viewclass: 'VariousButtons'

で、RecycleViewのリストに入れる、ボタン(VariousButtons)の設定(後述)


        RecycleBoxLayout:
            default_size: None, sp(160)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(8)

で、ボタンのスペース1つずつのサイズを設定。

今回はあえて、大きめに設定。

 

pythonソース側では、

kv18-2a.py抜粋 (python部分)


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

        self.rv.data = []
        btn_list = ['ひつまぶし','味噌煮込みうどん','味噌カツ','台湾ラーメン' \
                    ,'手羽先','小倉トースト','きしめん','あんかけスパ','どて煮' \
                    ,'ういろう','甘口バナナスパ']
        for btn_list_any in btn_list:
            self.rv.data.append({'value': btn_list_any})

と、このリストの中身と、それをkvファイル側にデータを送る処理(self.rv.data.append

 

次にボタンの部分<VariousButtons>

kv18-2a.py抜粋 (kvファイル部分)


<VariousButtons>:
    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Button:
        text: root.value
        background_normal: ''
        background_color: 0.5, 0.5, 0.75, 1
        color: 1, 1 ,1 ,1
        on_press: root.on_select_button(self)

 

ここは、色設定以外は、ボタンが押されたときの処理の飛び先の設定。パラメータに自分自身を入れる。

 

で、その飛び先では、

kv18-2a.py抜粋 (python部分)


class VariousButtons(BoxLayout):
    def on_select_button(self, button):
        print('press:'+button.text)

kv側で自分自身を入れたので、それを利用して、printで表示する。

 

RecycleViewは、いろんな機能があるようだけど、ListViewの代替で使うには、こんな使い方でいいと思う。