我有一个应用程序,可以在其中从相同的textinput小部件动态创建屏幕小部件和recycleview按钮viewclass对象。动态创建的ProjectScreen小部件的名称与SelectableButton的字典中包含的值相同。
在单击具有相同名称的SelectableButton recycleview viewclass对象后,我很难切换到ProjectScreen小部件。下面的代码示例:
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'
当我在recycleview中按下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的调用将直接转到我的root小部件,后者是屏幕管理器小部件。 SelectableButton是否不是RV的子小部件,RV是ProjectListScreen的子小部件?因此,ScreenManager根窗口小部件下还是一个子窗口小部件?
感谢您的帮助。谢谢。
答案 0 :(得分:0)
一种可能的解决方案是将data
中的信息传递给RecycleView
,因为它必须在SelectableButton
中创建一个属性:
*。py
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, 'manager': self.manager}) # <---
*。kv
<SelectableButton>:
manager: None # <---
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 # <---