Reputation: 484
new to Kivy and having an issue with recycleView when it's used through a screen. If I set the screen to start off with self.manager = MainWidget() for testing then the data gets loaded ok but when setting it correctly to ScreenManager() self.recycleView is always NoneType and crashes when I try to set self.recycleView.data. I'm assuming it's some sort of reference issue as when I load it using on_parent with MainWidget it works
Going straight to MainWidget():
self.manager = MainWidget()
Using MyScreenManager()
self.manager = MyScreenManager()
Results in error:
File "C:/path/to/main.py", line 42, in on_parent {"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"} AttributeError: 'NoneType' object has no attribute 'data'
Process finished with exit code 1
main.py
from kivy.app import App
from kivy.properties import StringProperty, NumericProperty, BooleanProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from navigation_screen_manager import NavigationScreenManager
class MyScreenManager(NavigationScreenManager):
pass
class MainMenu(BoxLayout):
pass
class ItemWidget(BoxLayout):
id = NumericProperty()
name = StringProperty()
links_to = StringProperty()
is_disabled = BooleanProperty()
description = StringProperty()
def get_menu(self, id):
if id == 9:
quit()
else:
print("you pressed" + str(id))
class MainWidget(FloatLayout):
recycleView = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
print('initialized')
self.items = ['item1', 'item2']
def on_parent(self, widget, parent):
print(f'parent of {self} is {self.parent}')
self.recycleView.data = [
{"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"}
]
class TheLabApp(App):
manager = ObjectProperty(None)
def build(self):
self.manager = MyScreenManager()
# return main interface
return self.manager
TheLabApp().run()
thelab.kv
#: import navigation_screen_manager navigation_screen_manager
#: import utils kivy.utils
#:set color1 "#DD7835"
#:set color2 "#D8D8D8"
<CoverImage@CoverBehavior+Image>:
reference_size: self.texture_size
<MyScreenManager>
Screen:
name: "MainWidget"
MainWidget:
<ItemWidget>:
BoxLayout:
size_hint_max_x: dp(300)
size_hint_min_x: dp(150)
orientation: "vertical"
Button:
text_size: self.size
background_color: 0,0,0,0
halign: "left"
valign: "center"
text: root.name
#on_press: quit() #root.get_menu(root.id)
BoxLayout:
spacing: dp(10)
FitLabel:
font_size: dp(22)
bold: True
LeftAlignLabel:
text: "description"
color: utils.get_color_from_hex(color2)
<MainWidget>:
recycleView: recycleView
CoverImage:
source: 'images/menu_background.jpg'
canvas:
Color:
rgba: 0, 0, 0, .6
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: "vertical"
Image:
source: 'images/small_logo.png'
allow_stretch: True
size_hint: None, None
size: dp(150), dp(60)
pos_hint: { "center_x": .5 }
TitleLabel:
text: "Title Label"
BoxLayout:
padding: dp(20), dp(20)
RecycleView:
id: recycleView
viewclass: 'ItemWidget'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: "vertical"
spacing: dp(16)
<FitLabel@Label>:
size_hint: None, None
size: self.texture_size
<TitleLabel@FitLabel>:
font_size: dp(22)
bold: True
padding: dp(16), dp(3)
canvas.before:
Color:
rgb: utils.get_color_from_hex(color1)
Rectangle:
pos: self.pos
size: self.size
<LeftAlignLabel@Label>
text_size: self.size
halign: "left"
valign: "center"
canvas.before:
Color:
#rgb: utils.get_random_color()
rgba: 0, 0, 0, 0
Rectangle:
pos: self.pos
size: self.size
navigation_screen_manager.py
from kivy.uix.screenmanager import ScreenManager
class NavigationScreenManager(ScreenManager):
screen_stack = []
def push(self, screen_name):
if screen_name not in self.screen_stack:
self.screen_stack.append(self.current)
self.transition.direction = 'left'
self.current = screen_name
def pop(self):
if len(self.screen_stack) > 0:
screen_name = self.screen_stack[-1]
self.transition.direction = 'right'
del self.screen_stack[-1]
self.current = screen_name
Upvotes: 0
Views: 109
Reputation: 38962
Since your recycleView
is a Property
of MainWidget
, you can trigger setting the data when the recycleView
is set, like this:
class MainWidget(FloatLayout):
recycleView = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
print('initialized')
self.items = ['item1', 'item2']
def on_recycleView(self, widget, rv):
self.recycleView.data = [
{"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"}
]
Upvotes: 1