У меня есть приложение, в котором я могу динамически создавать виджет экрана и объект viewclass кнопки повторного просмотра из одного и того же текстового виджета.Имя динамически создаваемого виджета ProjectScreen совпадает со значением, содержащимся в dict для SelectableButton.
Мне трудно переключиться на виджет ProjectScreen после нажатия на объект ViewClass представления повторного просмотра SelectableButton с тем женазвание.Примеры кода ниже:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty, BooleanProperty
'''Library imports for recycleview'''
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview import RecycleViewBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.behaviors import FocusBehavior
class HomeScreen(Screen):
pass
class ProjectListScreen(Screen):
rv = ObjectProperty(None)
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = []
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
""" Add selection support to the Label """
index = 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):
name = project_name_text_input.text
project_list_screen = self.manager.get_screen('project_list_screen')
project_list_screen.rv.data.insert(0, {'value': 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))
project_name_text_input.text = ''
screen_manager = ScreenManager()
class ReportingApp(App):
def build(self):
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 RecycleView kivy.uix.recycleview.RecycleView
#:import RecycleViewBehavior kivy.uix.recycleview.RecycleView
#:import RecycleDataViewBehavior kivy.uix.recycleview.views.RecycleDataViewBehavior
#:import RecycleBoxLayout kivy.uix.recycleboxlayout.RecycleBoxLayout
#:import LayoutSelectionBehavior kivy.uix.recycleview.layout.LayoutSelectionBehavior
#:import FocusBehavior kivy.uix.behaviors.FocusBehavior
<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'
<SelectableButton>:
canvas.before:
Color:
rgba: 0.5, 0.5, 0.5, 1
Rectangle:
size: self.size
pos: self.pos
value: ''
text: root.value
on_press:
root.manager.current = root.value
<ProjectListScreen>:
rv: rv
BoxLayout:
orientation: 'vertical'
Label:
text: 'Current list of projects'
Button:
text: 'Back'
on_press:
root.manager.transition.direction = 'right'
root.manager.current = 'home_screen'
RV:
id: rv
scroll_type: ['bars', 'content']
scroll_wheel_distance: dp(114)
bar_width: dp(10)
viewclass: 'SelectableButton'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing: dp(2)
multiselect: False
touch_multiselect: False
<ProjectScreen>:
BoxLayout:
Label:
text: 'hook up project info here'
Button:
text: 'Back'
Я получаю следующую ошибку, когда нажимаю объект SelectableButton в повторном просмотре:
[INFO ] [Logger ] Record log in C:\Users\amars\.kivy\logs\kivy_18-09-29_32.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
[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
[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 69, 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 1364, in on_motion
self.dispatch('on_touch_up', 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 1400, in on_touch_up
if w.dispatch('on_touch_up', 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 1201, in on_touch_up
return super(ScreenManager, self).on_touch_up(touch)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 482, in on_touch_up
if child.dispatch('on_touch_up', 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 304, in on_touch_up
ret = super(RelativeLayout, self).on_touch_up(touch)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\widget.py", line 482, in on_touch_up
if child.dispatch('on_touch_up', 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 482, in on_touch_up
if child.dispatch('on_touch_up', 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\scrollview.py", line 848, in on_touch_up
if self.dispatch('on_scroll_stop', 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\scrollview.py", line 887, in on_scroll_stop
self.simulate_touch_down(touch)
File "C:\Users\amars\AppData\Local\Programs\Python\Python37-32\lib\site-packages\kivy\uix\scrollview.py", line 607, in simulate_touch_down
ret = super(ScrollView, 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\behaviors\focus.py", line 443, in on_touch_down
return super(FocusBehavior, 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\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 82, in <module>
root.manager.current = root.value
File "kivy\weakproxy.pyx", line 30, in kivy.weakproxy.WeakProxy.__getattr__
AttributeError: 'SelectableButton' object has no attribute 'manager'
Каким-то образом мне нужно, чтобы виджет SelectableButton «знал» менеджер экрана, чтобы я мог переключиться на нужный экран.
Насколько я понимаю, вызов root.manager будет идти непосредственно к моему корневому виджету, которыйвиджет менеджера экранаРазве SelectableButton не является дочерним виджетом RV, который является дочерним виджетом ProjectListScreen?И, следовательно, все еще дочерний виджет под корневым виджетом ScreenManager?
Любая помощь приветствуется.Спасибо.