Kivy:动态添加屏幕小部件时属性错误
Kivy: Attribute error when dynamically adding screen widget
我正在尝试在调用 add_project_screen 时在 ProjectScreen 动态 class 实例中创建。我想创建 ProjectScreen 的各种实例,每个实例都有不同的名称,名称是从 project_name_text_input 获得的。这是我的 .py 和 .kv 文件:
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()
这里是 .kv 文件:
#: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'
这是我的错误信息:
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
如您所见,每当我单击应用程序中的按钮以调用 add_project_screen 方法时,应用程序将停止在 python 文件的第 38 行。 add_project_list_item 方法似乎适用于列表视图。
谢谢。
问题 - 属性错误
AttributeError
的原因是拼写错误,class 规则中的 button:
,<ProjectScreen>:
解决方案
将button:
替换为Button:
建议
kv 文件
- 将动态 class、
<ProjectScreen@Screen>:
替换为 class 规则、<ProjectScreen>:
- 将
BoxLayout:
小部件实例化为 class 规则的子项,<ProjectScreen>:
因为有标签和按钮小部件,并防止小部件重叠。
片段
<ProjectScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'hook up project info here'
Button:
text: 'Back'
Python代码
- 删除导入语句,
from kivy.factory import Factory
- 从
add_project_screen()
方法中删除 s = Factory.ProjectScreen(name=name)
- 将
self.manager.add_widget(s)
替换为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))
例子
main.py
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()
reporting.kv
#: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'
输出
我正在尝试在调用 add_project_screen 时在 ProjectScreen 动态 class 实例中创建。我想创建 ProjectScreen 的各种实例,每个实例都有不同的名称,名称是从 project_name_text_input 获得的。这是我的 .py 和 .kv 文件:
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()
这里是 .kv 文件:
#: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'
这是我的错误信息:
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
如您所见,每当我单击应用程序中的按钮以调用 add_project_screen 方法时,应用程序将停止在 python 文件的第 38 行。 add_project_list_item 方法似乎适用于列表视图。
谢谢。
问题 - 属性错误
AttributeError
的原因是拼写错误,class 规则中的 button:
,<ProjectScreen>:
解决方案
将button:
替换为Button:
建议
kv 文件
- 将动态 class、
<ProjectScreen@Screen>:
替换为 class 规则、<ProjectScreen>:
- 将
BoxLayout:
小部件实例化为 class 规则的子项,<ProjectScreen>:
因为有标签和按钮小部件,并防止小部件重叠。
片段
<ProjectScreen>:
BoxLayout:
orientation: 'vertical'
Label:
text: 'hook up project info here'
Button:
text: 'Back'
Python代码
- 删除导入语句,
from kivy.factory import Factory
- 从
add_project_screen()
方法中删除s = Factory.ProjectScreen(name=name)
- 将
self.manager.add_widget(s)
替换为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))
例子
main.py
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()
reporting.kv
#: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'