0

当我从流中接收数据时,我需要刷新回收视图。当我运行下面的代码时,我看到

AttributeError:“kivy.properties.DictProperty”对象没有属性“requests_recycle_view”

它来自recycle_view_list我认为实例存在一些问题但无法解决的方法。当我评论self.ids.requests_recycle_view.data = self.requests_tabrefresh_recycle_view从按钮运行时,它可以工作 - 我的意思是它刷新屏幕上的列表,但我需要它在requests_tab流中的数据更改时自动运行。

from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import pyrebase
from kivy.properties import  ListProperty

config = {
    "apiKey": "String",
    "authDomain": "String",
    "databaseURL": "String",
    "projectId": "String",
    "storageBucket": "String",
    "messagingSenderId": "String"
  };

firebase = pyrebase.initialize_app(config)
db = firebase.database()

Builder.load_file('kv/main.kv')




#-------------------------------------------------------------ScreenManager

class ScreenManagement(ScreenManager):
    pass




#--------------------------------------------------------------RequestScreen

class RequestScreen(Screen):

    requests_tab =  ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def refresh_recycle_view(self):
        print('refresh',  self.requests_tab)
        self.ids.requests_recycle_view.data = self.requests_tab


    def recycle_view_list(self, listFromStream):
        print("recycle_view_list", listFromStream)

        self.requests_tab = listFromStream
        self.ids.requests_recycle_view.data = self.requests_tab

    @classmethod
    def setRequestTab(cls, tab):
        print("setRequestTab", tab)
        cls.recycle_view_list(RequestScreen ,tab)





# ------------------------------------------------------------stream_handler
def stream_handler(message):
    print(message["event"])  # put
    print(message["path"])  # /-K7yGTTEp7O549EzTYtI
    print(message["data"])  # {'title': 'Pyrebase', "body": "etc..."}

    pyreMessage = [{'text': message["data"]}]

    RequestScreen.setRequestTab(pyreMessage)



db.child("Requests").stream(stream_handler)




#---------------------------------------------------------------StreamApp
class StreamApp(App):
    def build(self):

        sm = ScreenManagement()
        sm.add_widget(RequestScreen(name="Bajot II"))
        return sm

if __name__ == '__main__':
    StreamApp().run()

主文件

#main.kv
#:import FadeTransition kivy.uix.screenmanager.FadeTransition


<ScreenManagement>:
    transition: FadeTransition()
    RequestScreen:

<CustLabel@Label>
    halign: 'right'
    valign: 'middle'
    width: 80

<RequestScreen>
    name: "RequestScreen"

    requests_tab:   requests_recycle_view.data


    Button:
        size_hint_x: None
        width: 42
        text: "Done"
           on_press:   root.refresh_recycle_view()



    BoxLayout:
        #size_hint_y: None

        RecycleView:
            id: requests_recycle_view
            viewclass: 'CustLabel'
            data: root.requests_tab
            RecycleBoxLayout:
                spacing: 15
                default_size: 100, dp(25)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
4

1 回答 1

0

我无法对此进行测试(我没有您的数据库),但我认为它会起作用。我认为您关于实例的陈述是正确的。在下面修改后的代码中,我改成setRequestTab了一个实例方法:

from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from kivy.app import App
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import pyrebase
from kivy.properties import  ListProperty

config = {
    "apiKey": "String",
    "authDomain": "String",
    "databaseURL": "String",
    "projectId": "String",
    "storageBucket": "String",
    "messagingSenderId": "String"
  };

firebase = pyrebase.initialize_app(config)
db = firebase.database()

Builder.load_file('kv/main.kv')




#-------------------------------------------------------------ScreenManager

class ScreenManagement(ScreenManager):
    pass




#--------------------------------------------------------------RequestScreen

class RequestScreen(Screen):

    requests_tab =  ListProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def refresh_recycle_view(self):
        print('refresh',  self.requests_tab)
        print(self.ids.requests_recycle_view)
        self.ids.requests_recycle_view.data = self.requests_tab


    def recycle_view_list(self, listFromStream):
        print("recycle_view_list", listFromStream)

        self.requests_tab = listFromStream
        self.ids.requests_recycle_view.data = self.requests_tab

    def setRequestTab(self, tab):
        print("setRequestTab", tab)
        self.recycle_view_list(tab)




# ------------------------------------------------------------stream_handler
def stream_handler(message):
    print(message["event"])  # put
    print(message["path"])  # /-K7yGTTEp7O549EzTYtI
    print(message["data"])  # {'title': 'Pyrebase', "body": "etc..."}

    pyreMessage = [{'text': message["data"]}]

    App.get_running_app().requestScreen.setRequestTab(pyreMessage)



db.child("Requests").stream(stream_handler)




#---------------------------------------------------------------StreamApp
class StreamApp(App):
    def build(self):

        sm = ScreenManagement()
        self.requestScreen = RequestScreen(name="Bajot II")
        sm.add_widget(self.requestScreen)
        return sm

if __name__ == '__main__':
    StreamApp().run()

我在 中保存了对 的引用RequestScreenStreamApp然后在stream_handler(). 这允许我setRequestTab()作为实例方法调用。同样,此代码未经测试,因此可能存在一些错误。

于 2019-02-26T14:20:14.817 回答