KivyMD跨Screen类传递变量异常:无法获取输入框内容
KivyMD屏幕间变量传递问题:获取初始值而非输入框内容
我在开发KivyMD应用时,遇到了屏幕间变量传递的问题。从HomeScreen切换到ResultsScreen时,获取到的是HomeScreen的__init__方法中定义的初始值"dog",而不是通过get_text函数获取的输入框内容。
我的Python脚本
from kivymd.app import MDApp, Builder from kivy.core.window import Window from kivy.uix.screenmanager import Screen, ScreenManager from kivy.properties import StringProperty from api import gen_5_images # --- this changes the app's default background --- # Window.clearcolor = (.9, .9, .9, 1) Window.size = (400, 500) class HomeScreen(Screen): source = StringProperty() def __init__(self, **kwargs): super(HomeScreen, self).__init__(**kwargs) self.text = 'dog' def get_text(self): self.text = self.ids.input.text return self.text class ResultsScreen(HomeScreen): source = StringProperty() def on_manager(self, *args): # gets run when manager property is changed self.urls = gen_5_images(self.manager.get_screen('home').text) self.source = self.urls[0] class Main(MDApp): def build(self): Builder.load_file("layout.kv") sm = ScreenManager() sm.add_widget(HomeScreen(name='home')) sm.add_widget(ResultsScreen(name='results')) return sm Main().run()
我的KV文件
#:import hex kivy.utils.get_color_from_hex <HomeScreen>: name: 'home' MDFloatLayout: md_bg_color: hex('#003153') # background color MDLabel: text: "DreamGen" color: hex('#f5deb3') halign: "center" pos_hint: {"center_x": .5, "center_y": .9} font_size: "40sp" font_name: "Pacifico" MDTextField: id: input hint_text: "I had a dream..." hint_text_color_normal: hex("#00aae4") hint_text_color_focus: hex("#00aae4") helper_text_color_focus: hex("#00aae4") line_color_normal: hex('#003153') #make line color of background line_color_focus: hex('#003153') #make line color of background helper_text: "Write what comes to your mind" helper_text_mode: "on_focus" text_color_focus: hex('#add8e6') # color of text clicked text_color_normal: hex('#add8e6') # color of text without clicked mode: "rectangle" multiline: True size_hint_x: 0.7 size_hint_y: 0.5 pos_hint: {"center_x": .5, "center_y": .5} MDFillRoundFlatButton: text: "Generate" text_color: hex('#003153') md_bg_color: hex('#add8e6') pos_hint: {"center_x": .5, "center_y": .1} font_size: "15sp" on_release: root.get_text() root.manager.current = "results" <ResultsScreen>: name: 'results' MDFloatLayout: md_bg_color: hex('#003153') # background color MDLabel: text: "DreamGen" color: hex('#f5deb3') halign: "center" pos_hint: {"center_x": .5, "center_y": .9} font_size: "40sp" font_name: "Pacifico" AsyncImage: size_hint: None,None size: root.height, root.height source: root.source mipmap: True MDFillRoundFlatButton: text: "Try again!" text_color: hex('#003153') md_bg_color: hex('#add8e6') pos_hint: {"center_x": .5, "center_y": .1} font_size: "15sp" on_release: root.manager.current = "home"
问题原因
ResultsScreen的on_manager方法只会在屏幕首次被添加到ScreenManager时触发一次,后续切换屏幕不会重新执行。因此它读取的是HomeScreen初始化时的text默认值,而非用户输入后更新的最新值。
修复方案
方案1:监听屏幕进入事件,每次获取最新数据
修改ResultsScreen类,去掉不必要的继承,改用on_pre_enter事件(每次进入屏幕前都会触发)来获取最新的输入内容:
class ResultsScreen(Screen): # 不再继承HomeScreen,保持屏幕独立性 source = StringProperty() def on_pre_enter(self, *args): # 每次切换到该屏幕时,获取HomeScreen的最新text值 home_screen = self.manager.get_screen('home') self.urls = gen_5_images(home_screen.text) self.source = self.urls[0]
方案2:使用Kivy Property实现响应式更新
将HomeScreen的text改为StringProperty,这样变量变化时可以自动被监听(可选,进一步优化数据传递):
class HomeScreen(Screen): source = StringProperty() text = StringProperty('dog') # 用StringProperty替代普通变量 def get_text(self): self.text = self.ids.input.text
然后ResultsScreen依然使用on_pre_enter方法获取最新值即可。
额外优化建议
- 避免让
ResultsScreen继承HomeScreen,两个屏幕是独立组件,继承会引入不必要的属性和方法,增加代码复杂度。 - 可以在
get_text方法中添加空值判断,避免传入空文本给gen_5_images函数导致异常。
内容的提问来源于stack exchange,提问作者Marco Rodrigues
相关产品推荐
相关产品推荐

