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

从Popup修改Screen控件文本时触发ScreenManagerException错误求助

解决Kivy Popup修改Screen文本时的ScreenManagerException错误

错误根源

你在MyPopup的channge方法里调用Manager()会创建一个全新的ScreenManager实例,而不是当前App正在运行的那个,这个新实例里根本没有添加ScreenOne,所以会抛出找不到屏幕的错误。另外你尝试的ScreenOne.ids.lb.text写法也不对,因为ScreenOne是类而非实例,不能直接通过类访问ids。

可行解决方法

方案1:通过App实例获取当前ScreenManager

修改MyPopup的方法,直接获取当前App的根控件(即已存在的Manager实例):

class MyPopup(Popup):
    def change(self):  # 修正拼写错误:channge -> change
        # 获取当前运行的App实例,再获取根控件
        app = App.get_running_app()
        screen_one = app.root.get_screen("ScreenOne")
        screen_one.ids.lb.text = "this text"

方案2:打开Popup时传递当前Screen的引用

在kv文件里打开Popup时,把当前Screen实例传入:

Button:
    text: "go to popup"
    on_press: Factory.MyPopup(screen=root).open()  # 传递ScreenOne实例

然后修改MyPopup类,接收并使用这个引用:

from kivy.properties import ObjectProperty  # 需要导入该类

class MyPopup(Popup):
    screen = ObjectProperty(None)  # 定义属性接收Screen实例
    def change(self):
        self.screen.ids.lb.text = "this text"

额外需要修正的拼写错误

代码里还有几处拼写错误会导致运行异常:

  • Python文件里的channge改为change
  • kv文件里的oriental改为orientation(GridLayout的方向属性为orientation)
  • 替换代码里的"为正常双引号"

修正后的完整代码

test.py

import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty

class ScreenOne(Screen):
    pass

class MyPopup(Popup):
    screen = ObjectProperty(None)
    
    def change(self):
        # 方案1代码(注释掉方案2代码即可用):
        # app = App.get_running_app()
        # screen_one = app.root.get_screen("ScreenOne")
        # screen_one.ids.lb.text = "this text"
        
        # 方案2代码
        self.screen.ids.lb.text = "this text"

class Manager(ScreenManager):
    pass

kv = Builder.load_file("test.kv")

class appApp(App):
    def build(self):
        return kv

if __name__ == "__main__":
    appApp().run()

test.kv

#:import Factory kivy.factory.Factory

Manager:
    ScreenOne:

<ScreenOne>:
    name: "ScreenOne"
    GridLayout:
        cols: 1
        Label:
            id: lb
            text: "Text"
        Button:
            text: "go to popup"
            # 方案1用此行
            # on_press: Factory.MyPopup().open()
            # 方案2用此行
            on_press: Factory.MyPopup(screen=root).open()

<MyPopup>:
    name: "MyPopup"
    size_hint: .4,.8
    GridLayout:
        orientation: "vertical"
        cols: 2
        Button:
            text: "change text in Screen"
            on_press: root.change()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:17:34