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

如何在其他类中访问Kivy指定Screen内的成员控件

问题根因

你的代码存在4个核心错误,导致无法正确定位并启用目标按钮:

  • 错误使用ScreenManager类直接调用get_screen()实例方法:get_screen()必须绑定ScreenManager的实际运行实例才能调用,直接用类调用会缺少实例参数抛出异常。
  • Screen名称传参错误:get_screen()需要传入目标Screen的name属性值,你代码里S_Primary的name是win_Main,但传入的是内部BoxLayout的id值scr_primary,无法匹配到对应Screen。
  • KV语法错误:KV中定义id时不需要加引号,加引号会导致id无法被注册到组件的ids字典中,后续无法通过ids.xxx访问对应组件。
  • 滥用全局变量传递Popup实例,不仅容易引发引用异常、内存泄漏,也完全没有必要。
修正后代码

Python部分

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import ScreenManager, Screen

class S_Mananager(ScreenManager):
    pass

class S_Primary(Screen):
    def show_pop_up(self):
        # 局部创建Popup即可,无需全局存储
        popup = Popup( 
            content     = PupPass(), 
            size_hint   = (None, None), 
            size        = (250, 300)
        )
        popup.open()

class PupPass(BoxLayout):
    def btn_OK(self):
        # 当前组件是Popup的content,parent属性就是Popup实例,直接调用关闭
        self.parent.dismiss()
        # 获取运行中的App实例,root属性即为KV中定义的S_Mananager实例
        screen_manager = App.get_running_app().root
        # 传入正确的Screen名称获取目标Screen,再通过ids访问按钮
        primary_screen = screen_manager.get_screen("win_Main")
        primary_screen.ids.btn_enable_me.disabled = False

class S_Secondary(Screen):
    pass

class Screens(App):
    def build(self):
        # 显式返回根组件,避免依赖自动加载的隐式逻辑
        return S_Mananager()

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

KV部分(文件名为screens.kv,和App类名对应)

<PupPass>:
    orientation:    "vertical"
    Label:
        text:       "Label"
    Button:
        text:       "OK"
        on_release: root.btn_OK()

S_Mananager:
    S_Primary:
        # 直接在Screen实例化处定义name,和内部组件id区分,避免写错
        name: "win_Main"
    S_Secondary:

<S_Primary>:
    BoxLayout:
        id:             scr_primary
        orientation:    "vertical"
        Label:
            text:           'Label'
        Button:
            text:           'Button'
            on_release:     root.show_pop_up()
        Button:
            id:             btn_enable_me
            text:           'Enable Me by Popup !'
            on_release:     root.show_pop_up()
            disabled:       True

<S_Secondary>:
额外优化建议
  • Kivy中访问组件遵循固定链路,不需要全局变量传参:任意Python代码中可通过App.get_running_app()获取当前App实例,通过app.root访问根组件;子组件可通过self.parent访问父组件,通过self.ids访问当前规则下定义了id的子组件。
  • KV语法中id后直接跟标识符即可,不要加引号,否则id不会被注册。
  • 普通布局类作为子组件时,默认会填充父组件的可用空间,不需要手动写size: root.width, root.height,手动设置反而会导致窗口缩放时布局适配异常。
  • 类名遵循Python大驼峰命名规范,不要用小写开头的类名,提升代码可读性。

内容的提问来源于stack exchange,提问作者BlueHawk77

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:00:54