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

如何在Kivy的App类与ScreenManager的多Screen间共享变量?

问题描述

我正在开发一个简单应用,需要在初始页面获取用户名。我在testApp类中定义了一个变量,希望在继承Screen的其他类中对其进行读写操作。尝试了self.root、self.parent、self.manager等多种方式,但都无法实现。我本身不太擅长面向对象编程,之前的相关问题都已解决,现在学习ScreenManager时遇到了这个难题。

现有代码

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.properties import Clock
from kivy.properties import StringProperty


class MainMenu(Screen):
    pass

class secondMenu(Screen):
    def __init__(self,**kwargs):
        super(secondMenu, self).__init__(**kwargs)

    def set_name(self,field):
        self.manager.parent.name = field.text

class thirdMenu(Screen):
    def __init__(self,**kwargs):
        super(thirdMenu, self).__init__(**kwargs)
        Clock.schedule_interval(self.update,1/60)
    
    def update(self,_):
        pass

class testApp(App):
    name = StringProperty('')


    def __init__(self,**kwargs):
        super(testApp, self).__init__(**kwargs)
        Clock.schedule_interval(self.update,1/60)

    def build(self):
        sm = ScreenManager()
        sm.add_widget(MainMenu(name='main'))
        sm.add_widget(secondMenu(name='second'))
        sm.add_widget(thirdMenu(name='third'))
        return sm
    def update(self,dt):
        pass
    def on_name(self):
        print(self.name)

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

kv文件

MainMenu:


<MainMenu>:
    canvas.before:
        Color:
            rgb:(.3,.6,.7)
        Rectangle:
            size: self.size
    GridLayout:
        cols: 1
        Label:
            text: 'lading page'
            color:(.30,.2,.9)
        Button:
            text:'go to next page'
            on_press: root.manager.current = 'second'

<secondMenu>:
    canvas.before:
        Color:
            rgb:(.3,.6,.7)
        Rectangle:
            size: self.size
    GridLayout:
        cols: 1
        Label:
            text: 'enter info'
            color:(.30,.2,.9)
        TextInput:
            id:input_name
            text:'enter your name'
            on_text_validate: root.set_name(self)
            multiline: False
        Button:
            text:'go to next page'
            on_press: 
                root.manager.current = 'third'
                root.manager.transition.direction = 'up'


<thirdMenu>:
    canvas.before:
        Color:
            rgb:(.3,.6,.7)
        Rectangle:
            size: self.size
    GridLayout:
        cols: 1
        Label:
            id:label_name
            text: ''
            color:(.30,.2,.9)

解决方案

通过App.get_running_app()可以直接获取当前运行的testApp实例,从而访问其中定义的name变量,无需依赖self.manager.parent这类错误路径。

修改后的关键代码

  1. 更新secondMenu的set_name方法:
def set_name(self, field):
    App.get_running_app().name = field.text
  1. 在thirdMenu中读取并显示用户名,可直接绑定到Label的text属性,无需使用Clock轮询:
    修改kv文件中的thirdMenu部分:
<thirdMenu>:
    canvas.before:
        Color:
            rgb:(.3,.6,.7)
        Rectangle:
            size: self.size
    GridLayout:
        cols: 1
        Label:
            id:label_name
            text: app.name  # 直接绑定到App的name属性
            color:(.30,.2,.9)

这样就能实现不同Screen对App类中name变量的读写共享,同时也可以选择使用id来传递数据,但通过App实例共享变量的方式更适合全局状态的管理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:57:24