Kivy RecycleView 进入屏幕后不显示数据
Kivy RecycleView not showing data after moving into a screen
我修改了一个 Kivy RecycleView 示例并将其放入带有菜单的屏幕中,但现在它显示的是空页面而不是数据。我怀疑根已更改,但我无法将 RecycleView 连接到正确的源。
老实说,我认为我必须更多地学习如何在不同对象之间正确 link。
我修改后的版本有问题:
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
KV = """
<SomeMenu_ActionBar@ActionBar>:
ActionView:
id: ActionView
HiddenIcon_ActionPrevious:
ActionButton:
text: 'Stop'
on_release: app.stop()
<HiddenIcon_ActionPrevious@ActionPrevious>:
<MainBox>:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
# source: 'data/background.png'
MyManager:
id: sm
RVScreen:
id: rvscreen
SomeMenu_ActionBar:
id: ActionBar
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
<RVScreen>:
id: "rvscreen"
BoxLayout:
orientation: "vertical"
RecycleView:
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()
"""
class RecycleItem(RecycleDataViewBehavior, BoxLayout):
owner = ObjectProperty()
index = NumericProperty(0)
input_text = StringProperty()
label_text = StringProperty()
def set_text(self, text):
if self.owner is not None:
self.owner.data[self.index]['input_text'] = text
def refresh_view_attrs(self, rv, index, data):
self.index = index
return super(RecycleItem, self).refresh_view_attrs(rv, index, data)
class MainBox(BoxLayout):
"""Mainbox under MainApp
It contains the ScreenManager
"""
pass
class RVScreen(Screen):
pass
class MyManager(ScreenManager):
"""The screen manager that handles app screens
"""
pass
class Test(App):
data = ListProperty()
def build(self):
self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
Builder.load_string(KV)
return MainBox()
Test().run()
原始工作示例:
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder
KV = """
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
<RVScreen>:
BoxLayout:
orientation: "vertical"
RecycleView:
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()
"""
class RecycleItem(RecycleDataViewBehavior, BoxLayout):
owner = ObjectProperty()
index = NumericProperty(0)
input_text = StringProperty()
label_text = StringProperty()
def set_text(self, text):
if self.owner is not None:
self.owner.data[self.index]['input_text'] = text
def refresh_view_attrs(self, rv, index, data):
self.index = index
return super(RecycleItem, self).refresh_view_attrs(rv, index, data)
class Test(App):
data = ListProperty()
def build(self):
self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
return Builder.load_string(KV)
Test().run()
您可以通过多种方式定义 root
小部件。
如果您有 build
method in the App
's subclass and it returns some Widget
, it will be set as the root
小部件。或者您可以通过将 root
加载到 kv-rule 等
在这种情况下,在您的 kv-rule 中,您将 RecycleView
定义为 root
小部件,但您没有在 build
中使用它来将其设置为 root
.
与此同时,您从方法 build
返回了 MainBox
,因此它将用作 root
小部件。您再次在此处加载了 kv-rule,因此设计等将应用于此根小部件。
现在为了将 RecycleView
添加到 RVScreen
(如您在 中提到的)并将 MainBox
设置为 root
小部件(如您所做的已经)你可以修改你的 kvlang
如下:
<SomeMenu_ActionBar@ActionBar>:
ActionView:
id: ActionView
HiddenIcon_ActionPrevious:
ActionButton:
text: 'Stop'
on_release: app.stop()
<HiddenIcon_ActionPrevious@ActionPrevious>:
<MainBox>:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
# source: 'data/background.png'
MyManager:
id: sm
RVScreen:
id: rvscreen
SomeMenu_ActionBar:
id: ActionBar
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
<RVScreen>:
id: "rvscreen"
BoxLayout:
orientation: "vertical"
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()
我修改了一个 Kivy RecycleView 示例并将其放入带有菜单的屏幕中,但现在它显示的是空页面而不是数据。我怀疑根已更改,但我无法将 RecycleView 连接到正确的源。
老实说,我认为我必须更多地学习如何在不同对象之间正确 link。
我修改后的版本有问题:
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
KV = """
<SomeMenu_ActionBar@ActionBar>:
ActionView:
id: ActionView
HiddenIcon_ActionPrevious:
ActionButton:
text: 'Stop'
on_release: app.stop()
<HiddenIcon_ActionPrevious@ActionPrevious>:
<MainBox>:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
# source: 'data/background.png'
MyManager:
id: sm
RVScreen:
id: rvscreen
SomeMenu_ActionBar:
id: ActionBar
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
<RVScreen>:
id: "rvscreen"
BoxLayout:
orientation: "vertical"
RecycleView:
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()
"""
class RecycleItem(RecycleDataViewBehavior, BoxLayout):
owner = ObjectProperty()
index = NumericProperty(0)
input_text = StringProperty()
label_text = StringProperty()
def set_text(self, text):
if self.owner is not None:
self.owner.data[self.index]['input_text'] = text
def refresh_view_attrs(self, rv, index, data):
self.index = index
return super(RecycleItem, self).refresh_view_attrs(rv, index, data)
class MainBox(BoxLayout):
"""Mainbox under MainApp
It contains the ScreenManager
"""
pass
class RVScreen(Screen):
pass
class MyManager(ScreenManager):
"""The screen manager that handles app screens
"""
pass
class Test(App):
data = ListProperty()
def build(self):
self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
Builder.load_string(KV)
return MainBox()
Test().run()
原始工作示例:
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder
KV = """
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
<RVScreen>:
BoxLayout:
orientation: "vertical"
RecycleView:
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()
"""
class RecycleItem(RecycleDataViewBehavior, BoxLayout):
owner = ObjectProperty()
index = NumericProperty(0)
input_text = StringProperty()
label_text = StringProperty()
def set_text(self, text):
if self.owner is not None:
self.owner.data[self.index]['input_text'] = text
def refresh_view_attrs(self, rv, index, data):
self.index = index
return super(RecycleItem, self).refresh_view_attrs(rv, index, data)
class Test(App):
data = ListProperty()
def build(self):
self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
return Builder.load_string(KV)
Test().run()
您可以通过多种方式定义 root
小部件。
如果您有 build
method in the App
's subclass and it returns some Widget
, it will be set as the root
小部件。或者您可以通过将 root
加载到 kv-rule 等
在这种情况下,在您的 kv-rule 中,您将 RecycleView
定义为 root
小部件,但您没有在 build
中使用它来将其设置为 root
.
与此同时,您从方法 build
返回了 MainBox
,因此它将用作 root
小部件。您再次在此处加载了 kv-rule,因此设计等将应用于此根小部件。
现在为了将 RecycleView
添加到 RVScreen
(如您在 MainBox
设置为 root
小部件(如您所做的已经)你可以修改你的 kvlang
如下:
<SomeMenu_ActionBar@ActionBar>:
ActionView:
id: ActionView
HiddenIcon_ActionPrevious:
ActionButton:
text: 'Stop'
on_release: app.stop()
<HiddenIcon_ActionPrevious@ActionPrevious>:
<MainBox>:
orientation: 'vertical'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
# source: 'data/background.png'
MyManager:
id: sm
RVScreen:
id: rvscreen
SomeMenu_ActionBar:
id: ActionBar
<RecycleItem>:
orientation: 'horizontal'
Label:
text: root.label_text
TextInput:
text: root.input_text
on_text: root.set_text(self.text)
<RVScreen>:
id: "rvscreen"
BoxLayout:
orientation: "vertical"
RecycleView:
data: app.data
viewclass: 'RecycleItem'
RecycleBoxLayout:
spacing: 10
default_size: None, dp(80)
default_size_hint: 1, None
orientation: 'vertical'
size_hint_y: None
height: self.minimum_height
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
on_release: root.manager.current = root.manager.previous()