web-dev-qa-db-ja.com

ListViewの代わりとしてKivyRecycleView?それはどのように機能しますか?

私はまだKivyの初心者であることを前置きする必要があります。同様の質問を探してみましたが、古くなっているか不明です。

使用者が他のウィジェット(ボタンなど)と対話するために1つを選択できる要素のリストを表示するものを探していました。 ListViewのドキュメントページ に出くわしましたが、ListViewは非推奨であり、代わりに RecycleView を使用する必要があることが明確に示されています。

ここで問題となるのは、RecycleViewの使用方法に関するドキュメントが(少なくとも私には)あまり明確に見えないことです。それは間違いなく他のウィジェットよりも複雑で、私はそれを理解できないようです。

これをよりわかりやすい質問に分解するには:1。アイテムのリストとして機能するRecycleViewを定義するにはどうすればよいですか? 2.アイテムを提供するにはどうすればよいですか? 3.具体的には、一度に1つのアイテムのみを選択可能にし、何かが選択されたことを検出し、イベントで自動的に何かを選択するようにするには、どうすればよいですか?

ちなみに、私は可能な限りkv言語を使用することを好みます。

将来の使用のためにこれをより一般的に理解できるようにするドキュメントリソースを見つけたり理解したりするのに役立つ情報をいただければ幸いです。これらの複雑な機能のチュートリアルがどこかにあったらいいのにと思いますが、それが存在する場合、それを見つけるのは非常に困難です。

6
Federico S

以下の例は、Recycleviewを使用してボタンのリストを表示する方法を示しています。各ボタンを選択すると、ポップアップウィンドウが表示されます。

main.py

from kivy.app import App
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.properties import ListProperty, StringProperty, ObjectProperty


class MessageBox(Popup):

    def popup_dismiss(self):
        self.dismiss()


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
    """ Adds selection and focus behaviour to the view. """
    selected_value = StringProperty('')
    btn_info = ListProperty(['Button 0 Text', 'Button 1 Text', 'Button 2 Text'])


class SelectableButton(RecycleDataViewBehavior, Button):
    """ Add selection support to the Label """
    index = None

    def refresh_view_attrs(self, rv, index, data):
        """ Catch and handle the view changes """
        self.index = index
        return super(SelectableButton, self).refresh_view_attrs(rv, index, data)

    def on_press(self):
        self.parent.selected_value = 'Selected: {}'.format(self.parent.btn_info[int(self.id)])

    def on_release(self):
        MessageBox().open()


class RV(RecycleView):
    rv_layout = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'text': "Button " + str(x), 'id': str(x)} for x in range(3)]


class TestApp(App):
    title = "RecycleView Button Popup Demo"

    def build(self):
        return RV()


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

test.kv

#:kivy 1.10.0

<MessageBox>:
    title: 'Popup Message Box'
    size_hint: None, None
    size: 400, 400

    BoxLayout:
        orientation: 'vertical'
        Label:
            text: app.root.rv_layout.selected_value
        Button:
            size_hint: 1, 0.2
            text: 'OK'
            on_press:
                root.dismiss()

<SelectableButton>:
    # Draw a background to indicate selection
    canvas.before:
        Color:
            rgba: (0.0, 0.9, 0.1, 0.3)
        Rectangle:
            pos: self.pos
            size: self.size

<RV>:
    rv_layout: layout
    viewclass: 'SelectableButton'
    SelectableRecycleBoxLayout:
        id: layout
        default_size: None, dp(56)
        default_size_hint: 0.1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: "vertical"

出力

Recycleview of buttons with popups

3
ikolim

もっと簡単な例をしました。私の例では、クラスRecycleViewRowのウィジェットを含む各行のレイアウトをkv言語で変更することができます。例として、すでに各行にラベルとボタンを配置しました。これがもっと役立つことを願っています。

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.popup import Popup

Builder.load_string('''
#:kivy 1.10.0
#: import Popup kivy.uix.popup

<MessageBox>:
    title: 'Popup Message Box'
    size_hint: None, None
    size: 400, 400

    BoxLayout:
        orientation: 'vertical'
        Label:
            text: root.message
        Button:
            size_hint: 1, 0.2
            text: 'OK'
            on_press: root.dismiss()

<RecycleViewRow>:
    orientation: 'horizontal'
    Label:
        text: root.text
    Button:
        text: 'Show'
        on_press: app.root.message_box(root.text)

<MainScreen>:
    viewclass: 'RecycleViewRow'
    RecycleBoxLayout:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'                    
                    ''')

class MessageBox(Popup):
    message = StringProperty()

class RecycleViewRow(BoxLayout):
    text = StringProperty()   

class MainScreen(RecycleView):    
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        self.data = [{'text': "Button " + str(x), 'id': str(x)} for x in range(3)]

    def message_box(self, message):
        p = MessageBox()
        p.message = message
        p.open() 
        print('test press: ', message)

class TestApp(App):
    title = "RecycleView Direct Test"

    def build(self):
        return MainScreen()

if __name__ == "__main__":
    TestApp().run()
1
Randolfo