如何在 KivyMD 屏幕之间传递参数?

Posted

技术标签:

【中文标题】如何在 KivyMD 屏幕之间传递参数?【英文标题】:How do I pass an argument between KivyMD screens? 【发布时间】:2021-09-19 11:21:12 【问题描述】:

当从第一个屏幕转到第二个屏幕时,我想传递一个变量作为参数,以便 kivyMD 可以从存储在 excel 文件中的文本更新第二个屏幕。以下是我的应用程序功能的框架:

用户通过 KivyMD 中的导航抽屉到达屏幕 1,屏幕 1 为用户提供两个可点击的小型 MDCard 上的两个选项:

“将文本更改为 1” “将文本更改为 2”

点击其中一个后,应用会切换到带有单个大 MDCard 的屏幕 2,此 MDCard 上的文本应更改以反映用户选择的选项。

但是,kivy 正在从 excel 文件中提取要在大 MDCard 上显示的文本。 我想从屏幕 1 传递到屏幕 2 的变量只是一个数字(1 或 2),它会告诉 kivy 应该从 excel 文件中的哪一行提取文本

如果用户单击“将文本更改为 1”,则第一个屏幕应将“1”作为参数 row_x 传递给函数 def change_text() (参见屏幕 2 .py),这样excel第1行的文本可以显示在第二个屏幕上。我怎样才能做到这一点?

我总共有 4 个文件; 3个是.py文件(一个用于主应用程序,一个用于屏幕1,一个用于屏幕2)和excel文件

注意:在下面的代码中,屏幕 1 和 2 分别称为元素 1 和 2

Main.py:

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from element_1 import element_1_screen
from element_2 import element_2_screen

MainNavigation = '''
<ContentNavigationDrawer>:
    ScrollView:
        MDList:
            OneLineListItem:
                text: 'Go to Element 1'
                on_press:
                    root.nav_drawer.set_state("close")
                    root.screen_manager.current = "go_to_element_1_screen"

Screen:
    MDToolbar:
        id: toolbar
        pos_hint: "top": 1
        elevation: 10
        left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
    MDNavigationLayout:
        x: toolbar.height
        ScreenManager:
            id: screen_manager
            Screen:
                name: "words_nav_item"
            element_1_screen:
                name: "go_to_element_1_screen"
            element_2_screen:
                name: "go_to_element_2_screen"

        MDNavigationDrawer:
            id: nav_drawer
            ContentNavigationDrawer:
                screen_manager: screen_manager
                nav_drawer: nav_drawer
'''


class ContentNavigationDrawer(BoxLayout):
    screen_manager = ObjectProperty()
    nav_drawer = ObjectProperty()


class mainApp(MDApp):
    def build(self):
        self.theme_cls.primary_palette = "Red"
        return Builder.load_string(MainNavigation)


mainApp().run()

屏幕 1/元素 1

from kivy.lang import Builder
from kivymd.uix.screen import MDScreen

element_1_contents = '''
<element_1_screen>:
    MDGridLayout:
        rows: 2
        size: root.width, root.height
        pos_hint: "center_x": .8, "center_y": .2
        spacing: 40
        MDCard:
            orientation: 'vertical'
            size_hint: None, None
            size: "360dp", "120dp"
            ripple_behavior: True
            on_release:
                root.manager.current = "go_to_element_2_screen" 
            MDLabel:
                id: LabelTextID
                text: "Change Text to 1"
                halign: 'center'
    
        MDCard:
            orientation: 'vertical'
            size_hint: None, None
            size: "360dp", "120dp"
            ripple_behavior: True
            on_release:
                root.manager.current = "go_to_element_2_screen" 
            MDLabel:
                id: LabelTextID
                text: "Change Text to 2"
                halign: 'center'
                
        
'''

class element_1_screen(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        Builder.load_string(element_1_contents)

屏幕 2/元素 2

from kivy.lang import Builder
from kivymd.uix.screen import MDScreen
import openpyxl

element_2_contents = '''
<element_2_screen>:
    MDCard:
        orientation: 'vertical'
        size_hint: None, None
        size: "360dp", "360dp"
        pos_hint: "center_x": .5, "center_y": .5
        ripple_behavior: True
        focus_behavior: True
        on_release: root.manager.current = "go_to_element_1_screen"

        MDLabel:
            id: TextID
            text: "NOTHING HAS CHANGED"
            halign: 'center'

        MDLabel:
            text: "(Click here to return)"
            halign: 'center'
            
'''

class element_2_screen(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        path = "data.xlsx"
        self.wb_obj = openpyxl.load_workbook(path)
        self.sheet_obj = self.wb_obj.active
        Builder.load_string(element_2_contents)

    def change_text(self, row_x=0):
        row_number = self.sheet_obj.cell(row_x, column=1)
        self.ids.TextID.text = str(row_number.value)

而excel文件在A列只有两个条目:

Row 1: You have chosen 1
Row 2: You have chosen 2

【问题讨论】:

【参考方案1】:

我找到了答案,现在它可以完美运行。 Reddit 上的某个人 (u/Username_RANDINT) 帮助了我,他们是这样说的:

ScreenManager 有一个get_screen() 方法。你可以用它来获得 第二个屏幕的实例并调用change_text() 方法 那。在切换屏幕的同一个地方,添加另一行:

    on_release:
        root.manager.current = "go_to_element_2_screen"
        root.manager.get_screen("go_to_element_2_screen").change_text(1)

那么对另一张卡片也一样,只是传入 2 而不是 1。

【讨论】:

以上是关于如何在 KivyMD 屏幕之间传递参数?的主要内容,如果未能解决你的问题,请参考以下文章

使用参数在python脚本之间传递函数

如何在 XAML 页面之间传递值(参数)?

两个html的页面之间怎么传递参数啊

如何在页面之间传递Angular中的参数

如何在活动之间传递参数?

jquery怎么实现页面之间传递参数?