使用Kivy Screen Manager时访问self.ids控件触发AttributeError问题求助
解决KivyMD Screen中访问self.ids时的AttributeError问题
这个错误的核心原因很明确:在Screen的__init__方法执行阶段,kv布局文件还没有完成对该Screen实例的控件绑定,此时self.ids字典里还没有你在kv中定义的location等控件ID。直接在__init__里调用get_weather访问self.ids.location自然会触发KeyError,进而导致后续的AttributeError。
修复方案
我们可以通过两种方式确保在布局完全加载后再访问self.ids:
方案1:使用Clock.schedule_once延迟执行
通过Clock.schedule_once将get_weather的调用延迟到下一帧(参数0表示尽可能快,但会等待布局加载完成):
修改你的Weather类:
class Weather(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_interval(self.update_time, 60) city = 'Tokyo' # 延迟执行,确保kv布局已绑定到当前实例 Clock.schedule_once(lambda dt: self.get_weather(city), 0) def search_weather(self): self.get_weather(self.ids.city_name.text) def get_weather(self, city_name): self.ids.location.text = 'City : '+city_name def update_time(self, *args): print(datetime.now())
方案2:重写on_kv_post方法
Kivy的Widget类提供了on_kv_post方法,该方法会在kv布局文件完全加载并绑定到当前控件实例后自动调用,非常适合用来执行需要访问self.ids的初始化逻辑:
class Weather(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) Clock.schedule_interval(self.update_time, 60) self.default_city = 'Tokyo' def on_kv_post(self, base_widget): # kv布局加载完成后自动执行 self.get_weather(self.default_city) def search_weather(self): self.get_weather(self.ids.city_name.text) def get_weather(self, city_name): self.ids.location.text = 'City : '+city_name def update_time(self, *args): print(datetime.now())
额外小提示
你的Login类的action方法里有个小问题:print(f'logged in as {username}')中的username没有引用实例属性,应该改成self.username.text,否则会触发NameError:
def action(self): print(f'logged in as {self.username.text}')
这样修改后,你的应用应该就能正常运行,不会再出现AttributeError了。
内容的提问来源于stack exchange,提问作者DrHakeshi
相关产品推荐
相关产品推荐

