我的问题:我想要两个RecycleViews,第二个(CultureSubView)依赖于第一个(CultureView)中点击的内容。
它可以用来调用"更新"只要单击CultureView中的某些内容,CultureSubView的功能,但我不知道如何做到这一点。
因为必须在SelectableLabel中完成(可能需要额外的SelectableLabel,因为CultureView不需要额外的功能)
或者在kivy语言的CultureView中。
我还尝试过找到任何可以触发" on_press"在CultureView中然后更新CultureSubView,但我也没有找到任何选项。这个想法在代码中被注释掉了。
from kivy.app import App
from kivy.properties import StringProperty, BooleanProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
Builder.load_string('''
<ScreenCulture>:
BoxLayout:
orientation: 'vertical'
Label:
pos_hint: {"x": .45, "top": 1}
text: "Testosterone"
size_hint: .1, .1
GridLayout:
id: culture_layout
rows: 1
cols: 3
padding: dp(10)
spacing: dp(10)
orientation: 'horizontal'
CultureView:
id: culture_list_view
# on_press? culture_sub_view.update()
CultureSubView:
id: culture_sub_view
name_selected:
"Planet" if not culture_list_view.name_selected else culture_list_view.name_selected
CultureLabel:
id: culture_text
name_selected: "NVM" if not culture_sub_view.name_selected else culture_sub_view.name_selected
text_selected: "This is totally a test text" if not culture_sub_view.text_selected else culture_sub_view.text_selected
<CultureView>:
viewclass: 'SelectableLabel'
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureSubView>:
viewclass: 'SelectableLabel'
text_selected: ''
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureLabel>:
size_hint_y: .85
Label:
halign: 'left'
valign: 'middle'
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text_selected
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
Rectangle:
pos: self.pos
size: self.size
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
pass
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
rv.name_selected = rv.data[index]['text']
else:
print("selection removed for {0}".format(rv.data[index]))
class CultureView(RecycleView):
def __init__(self, **kwargs):
super(CultureView, self).__init__(**kwargs)
self.data = [
{"text": "Test1", "description": "testu"},
{"text": "Test2", "description": "testo"}
]
class CultureSubView(RecycleView):
planet_selected = StringProperty('')
def __init__(self, **kwargs):
super(CultureSubView, self).__init__(**kwargs)
self.selection_data = {
'': [],
'Test1': [
{"text": "test1.1", "description": "test1"},
{"text": "test1.2", "description": "text1"}
],
'Test2': [
{"text": "test2.1", "description": "text2"},
{"text": "test2.2", "description": "test2"}
]
}
self.data = self.selection_data[self.planet_selected]
def update(self):
print("Updating")
self.data = self.selection_data[self.planet_selected]
self.refresh_from_data()
class CultureLabel(ScrollView):
text_selected = StringProperty('')
name_selected = StringProperty('')
class ScreenCulture(Screen):
pass
screen_manager = ScreenManager()
screen_manager.add_widget(ScreenCulture(name="screen_culture"))
class TestApp(App):
def build(self):
return screen_manager
if __name__ == "__main__":
TestApp().run()
一如既往,感谢您的帮助:)
答案 0 :(得分:1)
由于该项目是 SelectableLabel ,请使用 on_touch_down 事件来调用方法 CultureSubView.update()。
调用方法 CultureSubView.update()有两个选项,一个选项来自kv文件,另一个来自Python脚本。这两个选项都使用了Kivy ObjectProperty。添加 ObjectProperty 以连接 culture_sub_view , ScreenManager 和 ScreenCulture 。有关详细信息,请参阅示例。
在此选项中, on_touch_down 事件被调用两次,因为我们有一个类SelectableLabel,它在两个地方使用,即CultureView和CultureSubView。
Builder.load_string('''
<ScreenManagement>:
screen_culture: screen_culture
ScreenCulture:
id: screen_culture
name: 'screen_culture'
<ScreenCulture>:
culture_sub_view: culture_sub_view
...
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
Rectangle:
pos: self.pos
size: self.size
on_touch_down:
print('on_touch_down:')
if self.selectable: \
app.root.screen_culture.culture_sub_view.update(self.text)
class SelectableLabel(RecycleDataViewBehavior, Label):
...
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
...
class ScreenCulture(Screen):
culture_sub_view = ObjectProperty(None)
class ScreenManagement(ScreenManager):
screen_culture = ObjectProperty(None)
class TestApp(App):
def build(self):
return ScreenManagement()
在此选项中,我们使用 App.get_running_app()。root.screen_culture.culture_sub_view.update()调用该方法,并将 self.text 传递给它。< / p>
Builder.load_string('''
<ScreenManagement>:
screen_culture: screen_culture
ScreenCulture:
id: screen_culture
name: 'screen_culture'
<ScreenCulture>:
culture_sub_view: culture_sub_view
class SelectableLabel(RecycleDataViewBehavior, Label):
...
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
App.get_running_app().root.screen_culture.culture_sub_view.update(self.text)
return self.parent.select_with_touch(self.index, touch)
...
class ScreenCulture(Screen):
culture_sub_view = ObjectProperty(None)
class ScreenManagement(ScreenManager):
screen_culture = ObjectProperty(None)
class TestApp(App):
def build(self):
return ScreenManagement()
from kivy.app import App
from kivy.properties import StringProperty, BooleanProperty, ObjectProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
Builder.load_string('''
<ScreenManagement>:
screen_culture: screen_culture
ScreenCulture:
id: screen_culture
name: 'screen_culture'
<ScreenCulture>:
culture_sub_view: culture_sub_view
BoxLayout:
orientation: 'vertical'
Label:
pos_hint: {"x": .45, "top": 1}
text: "Testosterone"
size_hint: .1, .1
GridLayout:
id: culture_layout
rows: 1
cols: 3
padding: dp(10)
spacing: dp(10)
orientation: 'horizontal'
CultureView:
id: culture_list_view
CultureSubView:
id: culture_sub_view
name_selected:
"Planet" if not culture_list_view.name_selected else culture_list_view.name_selected
CultureLabel:
id: culture_text
name_selected:
"NVM" if not culture_sub_view.name_selected else culture_sub_view.name_selected
text_selected:
"This is totally a test text" if not culture_sub_view.text_selected else culture_sub_view.text_selected
<CultureView>:
viewclass: 'SelectableLabel'
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureSubView>:
viewclass: 'SelectableLabel'
text_selected: ''
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureLabel>:
size_hint_y: .85
Label:
halign: 'left'
valign: 'middle'
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text_selected
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
Rectangle:
pos: self.pos
size: self.size
on_touch_down:
print('on_touch_down:')
if self.selectable: \
app.root.screen_culture.culture_sub_view.update(self.text)
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
pass
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
rv.name_selected = rv.data[index]['text']
else:
print("selection removed for {0}".format(rv.data[index]))
class CultureView(RecycleView):
def __init__(self, **kwargs):
super(CultureView, self).__init__(**kwargs)
self.data = [
{"text": "Test1", "description": "testu"},
{"text": "Test2", "description": "testo"}
]
class CultureSubView(RecycleView):
planet_selected = StringProperty('')
def __init__(self, **kwargs):
super(CultureSubView, self).__init__(**kwargs)
self.selection_data = {
'': [],
'Test1': [
{"text": "test1.1", "description": "test1"},
{"text": "test1.2", "description": "text1"}
],
'Test2': [
{"text": "test2.1", "description": "text2"},
{"text": "test2.2", "description": "test2"}
]
}
self.data = self.selection_data[self.planet_selected]
def update(self, name_selected):
print("Updating")
self.planet_selected = name_selected
self.data = self.selection_data[self.planet_selected]
self.refresh_from_data()
class CultureLabel(ScrollView):
text_selected = StringProperty('')
name_selected = StringProperty('')
class ScreenCulture(Screen):
culture_sub_view = ObjectProperty(None)
class ScreenManagement(ScreenManager):
screen_culture = ObjectProperty(None)
class TestApp(App):
def build(self):
return ScreenManagement()
if __name__ == "__main__":
TestApp().run()
from kivy.app import App
from kivy.properties import StringProperty, BooleanProperty, ObjectProperty
from kivy.uix.behaviors import FocusBehavior
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
Builder.load_string('''
<ScreenManagement>:
screen_culture: screen_culture
ScreenCulture:
id: screen_culture
name: 'screen_culture'
<ScreenCulture>:
culture_sub_view: culture_sub_view
BoxLayout:
orientation: 'vertical'
Label:
pos_hint: {"x": .45, "top": 1}
text: "Testosterone"
size_hint: .1, .1
GridLayout:
id: culture_layout
rows: 1
cols: 3
padding: dp(10)
spacing: dp(10)
orientation: 'horizontal'
CultureView:
id: culture_list_view
CultureSubView:
id: culture_sub_view
name_selected:
"Planet" if not culture_list_view.name_selected else culture_list_view.name_selected
CultureLabel:
id: culture_text
name_selected:
"NVM" if not culture_sub_view.name_selected else culture_sub_view.name_selected
text_selected:
"This is totally a test text" if not culture_sub_view.text_selected else culture_sub_view.text_selected
<CultureView>:
viewclass: 'SelectableLabel'
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureSubView>:
viewclass: 'SelectableLabel'
text_selected: ''
name_selected: ''
SelectableRecycleBoxLayout:
orientation: 'vertical'
default_size: None, dp(32)
default_size_hint: .6, None
size_hint: 1, .9
multiselect: False
touch_multiselect: False
<CultureLabel>:
size_hint_y: .85
Label:
halign: 'left'
valign: 'middle'
size_hint_y: None
height: self.texture_size[1]
text_size: self.width, None
text: root.text_selected
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.05, 0.5, .9, .8) if self.selected else (.5, .5, .5, 1)
Rectangle:
pos: self.pos
size: self.size
''')
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
pass
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
App.get_running_app().root.screen_culture.culture_sub_view.update(self.text)
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
rv.name_selected = rv.data[index]['text']
else:
print("selection removed for {0}".format(rv.data[index]))
class CultureView(RecycleView):
def __init__(self, **kwargs):
super(CultureView, self).__init__(**kwargs)
self.data = [
{"text": "Test1", "description": "testu"},
{"text": "Test2", "description": "testo"}
]
class CultureSubView(RecycleView):
planet_selected = StringProperty('')
def __init__(self, **kwargs):
super(CultureSubView, self).__init__(**kwargs)
self.selection_data = {
'': [],
'Test1': [
{"text": "test1.1", "description": "test1"},
{"text": "test1.2", "description": "text1"}
],
'Test2': [
{"text": "test2.1", "description": "text2"},
{"text": "test2.2", "description": "test2"}
]
}
self.data = self.selection_data[self.planet_selected]
def update(self, name_selected):
print("Updating")
self.planet_selected = name_selected
self.data = self.selection_data[self.planet_selected]
self.refresh_from_data()
class CultureLabel(ScrollView):
text_selected = StringProperty('')
name_selected = StringProperty('')
class ScreenCulture(Screen):
culture_sub_view = ObjectProperty(None)
class ScreenManagement(ScreenManager):
screen_culture = ObjectProperty(None)
class TestApp(App):
def build(self):
return ScreenManagement()
if __name__ == "__main__":
TestApp().run()