I am trying to create in instance of ProjectScreen dynamic class when add_project_screen is called. I want to create various instances of ProjectScreen, each with a different name, which is obtained from project_name_text_input. Here are my .py and .kv files:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.listview import ListItemButton
from kivy.factory import Factory
class ProjectListButton(ListItemButton):
pass
class HomeScreen(Screen):
pass
class ProjectListScreen(Screen):
project_list = ObjectProperty(None)
class ProjectScreen(Screen):
pass
class NewProjectScreen(Screen):
project_name_text_input = ObjectProperty(None)
project_address_text_input = ObjectProperty(None)
project_scope_text_input = ObjectProperty(None)
def add_project_list_item(self,project_name_text_input):
new_project_name = project_name_text_input.text
project_list_screen = self.manager.get_screen('project_list_screen')
project_list_screen.project_list.adapter.data.extend([new_project_name])
# Reset the ListView
project_list_screen.project_list._trigger_reset_populate()
#project_name_text_input.text = ''
def add_project_screen(self,project_name_text_input, project_address_text_input, project_scope_text_input):
name = project_name_text_input.text
s = Factory.ProjectScreen(name=name)
self.manager.add_widget(s)
class ReportingApp(App):
def build(self):
screen_manager = ScreenManager()
screen_manager.add_widget(HomeScreen(name="home_screen"))
screen_manager.add_widget(ProjectListScreen(name="project_list_screen"))
screen_manager.add_widget(NewProjectScreen(name="new_project_screen"))
return screen_manager
if __name__ == '__main__':
ReportingApp().run()
and here is .kv file:
#:kivy 1.10.1
#: import main main
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import ListItemButton kivy.uix.listview.ListItemButton
<HomeScreen>:
BoxLayout:
orientation: "vertical"
padding: 100
spacing: 25
Label:
size_hint_y: None
height: 150
text: "Site Visit Reporting App v1.1"
Button:
text: "New Project"
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'new_project_screen'
Button:
text: "Project List"
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'project_list_screen'
<NewProjectScreen>:
project_name_text_input: project_name
project_address_text_input: project_address
project_scope_text_input: project_scope
BoxLayout:
orientation: "vertical"
Label:
text: 'Project Name:'
TextInput:
id: project_name
Label:
text: 'Project Address:'
TextInput:
id: project_address
Label:
text: 'Project Scope:'
TextInput:
id: project_scope
BoxLayout:
padding: 15
spacing: 25
Button:
text: 'OK'
on_press:
root.add_project_list_item(project_name)
root.add_project_screen(project_name, project_address, project_scope)
Button:
text: 'Back'
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'home_screen'
<ProjectListScreen>:
project_list: project_list_view
BoxLayout:
orientation: 'vertical'
Label:
text: 'Current list of projects'
Button:
text: 'Back'
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'home_screen'
ListView:
id: project_list_view
adapter:
ListAdapter(data=[], cls=main.ProjectListButton)
<ProjectScreen@Screen>:
Label:
text: 'hook up project info here'
button:
text: 'Back'
Here are my error messages:
C:\Users\amars\AppData\Local\Programs\Python\Python37-32\python.exe C:/Users/amars/PycharmProjects/ReportingApp/main.py
[INFO ] [Logger ] Record log in C:\Users\amars\.kivy\logs\kivy_18-08-30_6.txt
[INFO ] [Kivy ] v1.10.1
[INFO ] [Python ] v3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)]
[INFO ] [Factory ] 194 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[WARNING] [Factory ] Ignored class "ProjectScreen" re-declaration. Current - module: None, cls: <class '__main__.ProjectScreen'>, baseclass: None, filename: None. Ignored - module: None, cls: None, baseclass: Screen, filename: C:\Users\amars\PycharmProjects\ReportingApp\reportingapp.kv.
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] GLEW initialization succeeded
[INFO ] [GL ] Backend used <glew>
[INFO ] [GL ] OpenGL version <b'4.3.0 - Build 20.19.15.4549'>
[INFO ] [GL ] OpenGL vendor <b'Intel'>
[INFO ] [GL ] OpenGL renderer <b'Intel(R) HD Graphics 4400'>
[INFO ] [GL ] OpenGL parsed version: 4, 3
[INFO ] [GL ] Shading version <b'4.30 - Build 20.19.15.4549'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <32>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\listview.py line 845.Called from C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\lang\builder.py line 582 by _apply_rule().
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\simplelistadapter.py line 49.Called from C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\listview.py line 859 by __init__().
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\adapter.py line 111.Called from C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\simplelistadapter.py line 55 by __init__().
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\abstractview.py line 42.Called from C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\listview.py line 865 by __init__().
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\listadapter.py line 185.Called from C:\Users\amars\PycharmProjects\ReportingApp\reportingapp.kv line 85 by <module>().
[WARNING] [Call to deprecated function __init__ in C]\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\adapter.py line 111.Called from C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\adapters\listadapter.py line 186 by __init__().
[INFO ] [Base ] Start application main loop
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "C:/Users/amars/PycharmProjects/ReportingApp/main.py", line 50, in <module>
ReportingApp().run()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\app.py", line 826, in run
runTouchApp()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\base.py", line 502, in runTouchApp
EventLoop.window.mainloop()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\core\window\window_sdl2.py", line 727, in mainloop
self._mainloop()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\core\window\window_sdl2.py", line 460, in _mainloop
EventLoop.idle()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\base.py", line 340, in idle
self.dispatch_input()
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\base.py", line 325, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\base.py", line 231, in post_dispatch_input
listener.dispatch('on_motion', etype, me)
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\core\window\__init__.py", line 1360, in on_motion
self.dispatch('on_touch_down', me)
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\core\window\__init__.py", line 1376, in on_touch_down
if w.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\screenmanager.py", line 1191, in on_touch_down
return super(ScreenManager, self).on_touch_down(touch)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 460, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\relativelayout.py", line 288, in on_touch_down
ret = super(RelativeLayout, self).on_touch_down(touch)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 460, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 460, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 460, in on_touch_down
if child.dispatch('on_touch_down', touch):
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\behaviors\button.py", line 151, in on_touch_down
self.dispatch('on_press')
File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\amars\PycharmProjects\ReportingApp\reportingapp.kv", line 61, in <module>
root.add_project_screen(project_name, project_address, project_scope)
File "C:/Users/amars/PycharmProjects/ReportingApp/main.py", line 38, in add_project_screen
s = Factory.ProjectScreen(name=name)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\relativelayout.py", line 265, in __init__
super(RelativeLayout, self).__init__(**kw)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\floatlayout.py", line 65, in __init__
super(FloatLayout, self).__init__(**kwargs)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\layout.py", line 76, in __init__
super(Layout, self).__init__(**kwargs)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 348, in __init__
Builder.apply(self, ignored_consts=self._kwargs_applied_init)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\lang\builder.py", line 469, in apply
self._apply_rule(widget, rule, rule, ignored_consts=ignored_consts)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\lang\builder.py", line 544, in _apply_rule
cls = Factory_get(cname)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\factory.py", line 130, in __getattr__
raise AttributeError
AttributeError
Process finished with exit code 1
As you can see, the app stops at line 38 in the python file, whenever I click the button in the app to call the add_project_screen method. add_project_list_item method seems to work for the listview.
Thank you.
The cause of the AttributeError
was due to typo error, button:
in class rule, <ProjectScreen>:
Replace button:
with Button:
<ProjectScreen@Screen>:
with class rule, <ProjectScreen>:
BoxLayout:
widget as children of class rule, <ProjectScreen>:
because there are Label and Button widgets, plus preventing widget overlapping.<ProjectScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'hook up project info here'
Button:
text: 'Back'
from kivy.factory import Factory
s = Factory.ProjectScreen(name=name)
from add_project_screen()
methodself.manager.add_widget(s)
with self.manager.add_widget(ProjectScreen(name=name))
def add_project_screen(self,project_name_text_input, project_address_text_input, project_scope_text_input):
name = project_name_text_input.text
self.manager.add_widget(ProjectScreen(name=name))
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.listview import ListItemButton
class ProjectListButton(ListItemButton):
pass
class HomeScreen(Screen):
pass
class ProjectListScreen(Screen):
project_list = ObjectProperty(None)
class ProjectScreen(Screen):
pass
class NewProjectScreen(Screen):
project_name_text_input = ObjectProperty(None)
project_address_text_input = ObjectProperty(None)
project_scope_text_input = ObjectProperty(None)
def add_project_list_item(self, project_name_text_input):
new_project_name = project_name_text_input.text
project_list_screen = self.manager.get_screen('project_list_screen')
project_list_screen.project_list.adapter.data.extend([new_project_name])
# Reset the ListView
project_list_screen.project_list._trigger_reset_populate()
#project_name_text_input.text = ''
def add_project_screen(self,project_name_text_input, project_address_text_input, project_scope_text_input):
name = project_name_text_input.text
self.manager.add_widget(ProjectScreen(name=name))
class ReportingApp(App):
def build(self):
screen_manager = ScreenManager()
screen_manager.add_widget(HomeScreen(name="home_screen"))
screen_manager.add_widget(ProjectListScreen(name="project_list_screen"))
screen_manager.add_widget(NewProjectScreen(name="new_project_screen"))
return screen_manager
if __name__ == '__main__':
ReportingApp().run()
#:kivy 1.11.0
#:import main main
#:import ListAdapter kivy.adapters.listadapter.ListAdapter
#:import ListItemButton kivy.uix.listview.ListItemButton
<HomeScreen>:
BoxLayout:
orientation: "vertical"
padding: 100
spacing: 25
Label:
size_hint_y: None
height: 150
text: "Site Visit Reporting App v1.1"
Button:
text: "New Project"
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'new_project_screen'
Button:
text: "Project List"
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'project_list_screen'
<NewProjectScreen>:
project_name_text_input: project_name
project_address_text_input: project_address
project_scope_text_input: project_scope
BoxLayout:
orientation: "vertical"
Label:
text: 'Project Name:'
TextInput:
id: project_name
Label:
text: 'Project Address:'
TextInput:
id: project_address
Label:
text: 'Project Scope:'
TextInput:
id: project_scope
BoxLayout:
padding: 15
spacing: 25
Button:
text: 'OK'
on_press:
root.add_project_list_item(project_name)
root.add_project_screen(project_name, project_address, project_scope)
Button:
text: 'Back'
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'home_screen'
<ProjectListScreen>:
project_list: project_list_view
BoxLayout:
orientation: 'vertical'
Label:
text: 'Current list of projects'
Button:
text: 'Back'
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'home_screen'
ListView:
id: project_list_view
adapter:
ListAdapter(data=[], cls=main.ProjectListButton)
<ProjectScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'hook up project info here'
Button:
text: 'Back'