I am trying to dynamically create OneLineListItems on my main Screen, but the id is not recognized. I tried a lot, but I'm not coming to a solution.
main.py :
class CustomDialogContent(MDGridLayout):
pass
class Content(BoxLayout):
manager = ObjectProperty()
nav_drw = ObjectProperty()
pass
class Demo(ScreenManager):
pass
class Main(MDApp):
def build(self):
return Demo()
def show_dialog(self):
close_button = MDFlatButton(text='Close', pos_hint={'x': 0, 'y': -.3}, on_release=self.close_dialog)
ok_button = MDFlatButton(text='OK', pos_hint={'x': 0, 'y': -.3}, on_release=self.ok_dialog)
self.dialog = MDDialog(
title="Dialog Title",
size_hint=(0.8, 0.3),
type="custom",
content_cls=CustomDialogContent(),
buttons=[ok_button, close_button],
auto_dismiss= False
)
self.dialog.open()
Here is my main including my classes, so far this part runs well, I have included a Navigationdrawer and a Dialog Box that opens upon Button press.
def post_text(self, text1, text2, *args):
print(text1)
print(text2)
if text1:
screen = self.root.ids.screen_manager.get_screen("First")
screen.ids.list_view.add_widget(OneLineListItem(text=text1))
screen.ids.list_view.add_widget(OneLineListItem(text=text2))
#self.ids.list_view.add_widget(OneLineListItem(text=text1))
#self.ids.list_view.add_widget(OneLineListItem(text=text1))
This is where my issue lies specifically, I don't understand why id list_view is not being recognized when it should be stored in the self.ids dictionary. Doing the latter which is commented out doesn't work either.
Here is the rest of my code, which is as well in my Main class
def ok_dialog(self, *args):
text_field_1 = self.dialog.content_cls.ids.text_field_1
text_field_2 = self.dialog.content_cls.ids.text_field_2
self.post_text(text_field_1.text, text_field_2.text)
self.close_dialog()
def close_dialog(self, *args):
self.dialog.dismiss()
Main().run()
This also works fine, here I call my post_text function and it passes the input text like it should.
main.kv:
#: import NoTransition kivy.uix.screenmanager.NoTransition
<CustomDialogContent>
#cols: 1
rows: 2
spacing: '12dp'
padding: '12dp'
size_hint_y: None
height: '120dp'
MDTextField:
id: text_field_1
size_hint_x: .5
hint_text: "Text Field 1"
MDTextField:
id: text_field_2
size_hint_x: .5
hint_text: "Text Field 2"
<Content>:
ScrollView:
MDList:
OneLineListItem:
text: "Go to screen 1"
on_release:
root.manager.transition = NoTransition()
root.manager.current = "First"
OneLineListItem:
text: "Go to screen 2"
on_release:
root.manager.transition = NoTransition()
root.manager.current = "Second"
<Demo>:
Screen:
MDTopAppBar:
pos_hint: {"top": 1}
#title: "Navigation Drawer"
evelation: 8
left_action_items: [["menu",lambda x: nav_drawer.set_state("open")]]
FloatLayout:
MDTextField:
hint_text: "Search"
#color_mode: 'custom'
max_text_length: 15
size_hint_x: 0.425
line_color_focus: 0.92, 0.25, 0.20
hint_text_color_normal: "red"
text_color_focus: '#ff0000'
text_color_normal: '#00ff00'
pos_hint: {"right": 1.0, "top": 1.0}
MDNavigationDrawer:
id: nav_drawer
Content:
manager: screen_manager
nav_drw: nav_drawer
MDNavigationLayout:
ScreenManager:
id: screen_manager
Screen:
id: main_screen
name: "First"
MDLabel:
text: "First Screen"
MDList:
id:list_view
name: "list_view"
MDIconButton:
icon:'android'
pos_hint: {"y":0.1, "x": 0.8}
on_release:
app.show_dialog()
Screen:
name: "Second"
MDLabel:
text: "2nd Screen"
As you can see list_view is defined in Screen (id: main_screen)
File "kivy\properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__
KeyError: 'list_view'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\addyi\PycharmProjects\KivyApp2\main.py", line 73, in <module>
Main().run()
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\app.py", line 955, in run
runTouchApp()
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\base.py", line 574, in runTouchApp
EventLoop.mainloop()
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\base.py", line 339, in mainloop
self.idle()
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\base.py", line 383, in idle
self.dispatch_input()
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\base.py", line 334, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\base.py", line 302, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivymd\uix\button\button.py", line 1187, in on_touch_up
return super().on_touch_up(touch)
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivymd\uix\behaviors\ripple_behavior.py", line 404, in on_touch_up
return super().on_touch_up(touch)
File "C:\Users\addyi\PycharmProjects\TestApp\venv\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1231, in kivy._event.EventObservers._dispatch
File "C:\Users\addyi\PycharmProjects\KivyApp2\main.py", line 65, in ok_dialog
self.post_text(text_field_1.text, text_field_2.text)
File "C:\Users\addyi\PycharmProjects\KivyApp2\main.py", line 53, in post_text
screen.ids.list_view.add_widget(OneLineListItem(text=text1))
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
I have also added the error code if anybody needs it
The ids
are created when the kv
file is loaded, and they are added to the ids
dictionary of the root widget that contains the id
. So, in your case, the list_view
id
is defined in the <Demo>
rule and that id
will appear in the ids
of the Demo
instance.
Try changing:
screen.ids.list_view.add_widget(OneLineListItem(text=text1))
screen.ids.list_view.add_widget(OneLineListItem(text=text2))
to:
self.root.ids.list_view.add_widget(OneLineListItem(text=text1))
self.root.ids.list_view.add_widget(OneLineListItem(text=text2))
this assumes that the post_text()
method is a method of your Main
class.