私はまだKivyの初心者であることを前置きする必要があります。同様の質問を探してみましたが、古くなっているか不明です。
使用者が他のウィジェット(ボタンなど)と対話するために1つを選択できる要素のリストを表示するものを探していました。 ListViewのドキュメントページ に出くわしましたが、ListViewは非推奨であり、代わりに RecycleView を使用する必要があることが明確に示されています。
ここで問題となるのは、RecycleViewの使用方法に関するドキュメントが(少なくとも私には)あまり明確に見えないことです。それは間違いなく他のウィジェットよりも複雑で、私はそれを理解できないようです。
これをよりわかりやすい質問に分解するには:1。アイテムのリストとして機能するRecycleViewを定義するにはどうすればよいですか? 2.アイテムを提供するにはどうすればよいですか? 3.具体的には、一度に1つのアイテムのみを選択可能にし、何かが選択されたことを検出し、イベントで自動的に何かを選択するようにするには、どうすればよいですか?
ちなみに、私は可能な限りkv言語を使用することを好みます。
将来の使用のためにこれをより一般的に理解できるようにするドキュメントリソースを見つけたり理解したりするのに役立つ情報をいただければ幸いです。これらの複雑な機能のチュートリアルがどこかにあったらいいのにと思いますが、それが存在する場合、それを見つけるのは非常に困難です。
以下の例は、Recycleviewを使用してボタンのリストを表示する方法を示しています。各ボタンを選択すると、ポップアップウィンドウが表示されます。
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()
#: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"
もっと簡単な例をしました。私の例では、クラス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()