我如何在 KivyMD 屏幕之间传递参数?
How do I pass an argument between KivyMD screens?
当从第一个屏幕转到第二个屏幕时,我想传递一个变量作为参数,以便 kivyMD 可以从 excel 文件中存储的文本更新第二个屏幕。以下是我的应用程序功能的框架:
用户通过 KivyMD 中的导航抽屉到达屏幕 1,屏幕 1 在两个可点击的小 MDCard 上向用户显示两个选项:
- “将文本更改为 1”
- “将文本更改为 2”
点击其中一个后,应用程序切换到屏幕 2,其中有一个大 MDCard,此 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
我找到了答案,现在可以完美运行了。 Reddit (u/Username_RANDINT) 上有人帮助了我,他们是这样说的:
The ScreenManager has a get_screen()
method. You could use it to get
the instance of the second screen and call the change_text()
method on
that. In the same place where you switch screens, add another line:
on_release:
root.manager.current = "go_to_element_2_screen"
root.manager.get_screen("go_to_element_2_screen").change_text(1)
Then the same for the other card, just pass in 2 instead of 1.
当从第一个屏幕转到第二个屏幕时,我想传递一个变量作为参数,以便 kivyMD 可以从 excel 文件中存储的文本更新第二个屏幕。以下是我的应用程序功能的框架:
用户通过 KivyMD 中的导航抽屉到达屏幕 1,屏幕 1 在两个可点击的小 MDCard 上向用户显示两个选项:
- “将文本更改为 1”
- “将文本更改为 2”
点击其中一个后,应用程序切换到屏幕 2,其中有一个大 MDCard,此 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
我找到了答案,现在可以完美运行了。 Reddit (u/Username_RANDINT) 上有人帮助了我,他们是这样说的:
The ScreenManager has a
get_screen()
method. You could use it to get the instance of the second screen and call thechange_text()
method on that. In the same place where you switch screens, add another line:
on_release:
root.manager.current = "go_to_element_2_screen"
root.manager.get_screen("go_to_element_2_screen").change_text(1)
Then the same for the other card, just pass in 2 instead of 1.