如何在其他类中访问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
相关产品推荐
相关产品推荐

