如何传递一个值来初始化 Kivy 中的屏幕小部件?

Posted

技术标签:

【中文标题】如何传递一个值来初始化 Kivy 中的屏幕小部件?【英文标题】:How to pass a value to initialize a screen widget in Kivy? 【发布时间】:2018-08-30 04:19:26 【问题描述】:

我正在使用 Kivy 作为我的项目制作一个旅行/旅游应用程序,我需要将一些值从一个小部件传递到另一个将显示位置信息的屏幕。

我可以使用此功能在不同屏幕之间共享信息 Kivy - Screen Manager - Accessing attribute in other class 方法,但是当我尝试从不是直接屏幕的小部件传递变量时,这似乎不起作用。


我有一个使用 RecycleView 创建的聊天界面,其中有一个按钮可以“查看更多”关于我们正在谈论的当前位置的信息,但是我无法将值从这个 Row 小部件传递到 LocationInfo 小部件/屏幕。

这里是相关代码

相关 Python 代码

class TourismRoot(ScreenManager):
    def open_location_info_page(self, locationname):
        self.current = 'LocationInfoPage'

class LocationInfo(Screen):
    cityname = StringProperty()
    def test_print(self):
        print(self.cityname)

相关KV代码

TourismRoot:
    id: screen_manager
    FirstTimeRun:
        id: firstrunid
        name: 'FirstRun'
        manager: screen_manager

    FirstTimeRun2:
        id: firstrun2id
        name: 'FirstRun_2'
        manager: screen_manager
        nickname: firstrunid.entered_nickname #taking value from another screen, works

    LoginScreen:
        id: loginscreenid
        name: 'Login'
        manager: screen_manager

    ChatBotScreen:
        id: chatbotid
        name: 'ChatBot'
        manager: screen_manager
        nickname: firstrunid.entered_nickname

    LocationInfo:
        id: locationinfo
        name: 'LocationInfoPage'
        manager: screen_manager
        cityname: chatbotid.ids.lb_chat_row #gives error

<Row>:
    BoxLayout:
        Label:
            id: lb_chat_row
            text: 'stuff'
    GridLayout:
        Button:
            id: bt_chat_row
            text: root.button_text
            font_size: "18dp"
            text_size: self.size
            on_release: app.root.open_location_info_page(root.ids.lb_chat_row.text)

<ChatBotScreen>
    ScrollView:
        size_hint_y: 85
        RecycleView:
            id: chatbase_list
            viewclass: 'Row'
            data: []
            RecycleBoxLayout:
                orientation: 'vertical'
                padding: "15dp", "45dp", "15dp", "15dp"
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height

如您所见,Row 小部件实际上是 RecycleView 的视图类,因此我不能简单地将其设为屏幕并传递值(我试过了,它弄乱了布局)。

当前代码给出以下错误:

 kivy.lang.builder.BuilderException: Parser: File "<inline>", line 47:
  ...
       45:        name: 'LocationInfoPage'
       46:        manager: screen_manager
  >>   47:        cityname: chatbotid.ids.lb_chat_row
       48:
       49:<Row>:
  ...
  BuilderException: Parser: File "<inline>", line 47:
  ...
       45:        name: 'LocationInfoPage'
       46:        manager: screen_manager
  >>   47:        cityname: chatbotid.ids.lb_chat_row
       48:
       49:<Row>:
  ...
  AttributeError: 'super' object has no attribute '__getattr__'

任何帮助都非常感谢~

【问题讨论】:

【参考方案1】:

在这种情况下,作为 .kv 语言的替代方案,您可以将值存储在缓存中,以便在需要时在屏幕之间传输。然后,您可以动态更新任何您想要的内容。

# Store value in Cache    
Cache.register('mycache')
Cache.append('mycache', 'mykey', value)

# Get value from Cache
value = Cache.get('mycache', 'mykey')

【讨论】:

我现在已经阅读了这个和 Cache 文档几次,但我真的不确定如何在我的情况下实现它,特别是因为我使用 kv 语言来定义所有小部件。您能否详细说明我如何使用它?非常感谢。 @RhinoFreak 抱歉,我的帖子对您​​的情况没有太大帮助。我已经编辑了,如果它不起作用,请告诉我。 @"M Yasin Y" 我使用了 chatbotid.ids.lb_chat_row.text 并且收到错误消息,说“超级”对象没有属性“getattr” . 谢谢你的帮助! @RhinoFreak 能否直接在 ChatBotScreen 上的 ScrollView 中添加另一个标签并尝试调用它?如果它有效,您的问题是标签未在给定的根上定义。在这种情况下,您可能需要使用默认视图类之一,或者如果可能的话将您的标签直接放入 RecycleView。此外,原因可能是 Kivy 找不到您的视图类。正如 Kivy 网站上所述,“无法找到视图时进行测试”仍在待办事项列表中。

以上是关于如何传递一个值来初始化 Kivy 中的屏幕小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如果未动态添加,如何正确删除Kivy中的小部件

从 Kivy 的另一个屏幕更改小部件

在 Kivy 中传递自定义小部件属性

更新另一个类中的 kivy 标签文本

如何将位于同一行的 Kivy 小部件移得更远?

如何获取在kivy中定义在屏幕小部件内的滑块的值