You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多文件Kivy项目跨屏幕更新元素报错的解决方案咨询

问题解决:AttributeError: 'Screen' object has no attribute 'update'

错误原因

你在main.py中给home屏幕嵌套了两层结构:先是一个原生Screen组件(id为home),然后把自定义的HomeScreen实例添加到这个原生Screen里。当你调用get_screen('home')时,获取到的是外层的原生Screen对象,而非你定义的带有update方法的HomeScreen实例,因此触发报错。

解决方案

直接让自定义的HomeScreen作为ScreenManager的子屏幕,不需要额外嵌套原生Screen容器。因为HomeScreen本身就是Screen的子类,完全可以直接作为独立屏幕使用。

修改步骤:

  1. 替换main.py中KV代码的外层Screen为HomeScreen
  2. 移除ManagerScreen中手动添加HomeScreen的代码
  3. 修正home.py中KV的按钮事件引用,确保正确访问内部的ScreenManager

修改后的代码片段:

main.py

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

from login import LoginScreen
from home import HomeScreen

Builder.load_string(
"""
<ManagerScreen>:
    Screen:
        id: login
        name: 'login'
    MDScreen:
        id: register
        name: 'register'
    HomeScreen:
        id: home
        name: 'home'

""" )

class ManagerScreen(ScreenManager):
    def __init__(self, **kwargs):
        super(ManagerScreen, self).__init__(**kwargs)
        self.ids.login.add_widget(LoginScreen())
        # 移除原有的self.ids.home.add_widget(HomeScreen())

class MainApp(MDApp):
    def build(self):
        sm = ManagerScreen()
        return sm

if __name__ == '__main__':
    MainApp().run()

home.py(修正重复ID和事件引用)

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

import sqlite3
from loading import LoadImage

Builder.load_string(
"""
#:import utils kivy.utils
<HomeScreen>:
    MDBoxLayout:
        orientation: 'vertical'
        MDBoxLayout:
            size_hint_y: None
            height: first.height
            MDRaisedButton:
                id: first
                text: "Ecran 1"
                on_press: root.ids.sm.current = 'firstscreen'
            MDRaisedButton:
                id: second
                text: "Ecran 2"
                on_press: root.ids.sm.current = 'secondscreen'
        ScreenManager:
            id: sm
            Screen:
                id: firstscreen
                name: 'firstscreen'
                MDRelativeLayout:
                    MDCard:
                        orientation: 'vertical'
                        md_bg_color: utils.get_color_from_hex('#3e55c9')
                        MDLabel:
                            id: lab
                            markup: True
                        MDRaisedButton:
                            id: buttontext
                            text: 'importer fichier'

            Screen:
                id: secondscreen
                name: 'secondscreen'

"""
    )

class HomeScreen(Screen):
    def __init__(self, **kwargs):
        super(HomeScreen, self).__init__(**kwargs)
        
    def update(self):
        self.ids.lab.text = "Bienvenu Monsieur"

login.py(无需修改,现在get_screen('home')将获取正确实例)

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
import sqlite3
from loading import LoadImage

Builder.load_string(
"""
<LoginScreen>:
    MDCard:
        size_hint: .5, .4
        pos_hint: {'center_x':.5, 'center_y':.5}
        orientation: 'vertical'
        padding: 10
        spacing: 10
        MDTextField:
            id: username
            hint_text: "Nom d'utilisateur"
        MDTextField:
            id: pwd
            hint_text: "Mot de passe"
        MDRaisedButton:
            text: 'Connexion'
            pos_hint: {'center_x':.5}
            on_press: root.log_in()
        MDTextButton:
            text: "Créez un compte si vous n'en avez pas!"
            pos_hint: {'center_x':.5}
            on_press: root.parent.parent.current = 'register'
"""
    )

class LoginScreen(MDRelativeLayout):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)

    def log_in(self):
        home_screen = self.parent.manager.get_screen('home')
        home_screen.update()
        self.parent.parent.current = 'home'

修改完成后,get_screen('home')将正确获取到带有update方法的HomeScreen实例,调用update()即可正常修改Label文本。

内容的提问来源于stack exchange,提问作者Borris Kouadja NIANGORAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 02:53:19