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

如何在含Screen Manager的Kivy文件b.py中调用运行a.py

问题原因分析

你遇到的问题核心在于错误地在RegisterWindow的初始化方法里调用了a.SplashApp().run()。Kivy的App.run()方法会启动一个独立的应用事件循环,一旦这个方法被调用,程序的执行流就会被这个循环完全占据——主应用(b.py里的Application)的ScreenManager根本没机会正常启动和运行,所以你只会看到a.py的界面,主应用的屏幕切换逻辑完全被阻塞了。

正确的解决方案

我们的目标是把a.py里的LandingScreen作为一个UI组件集成到b.py的RegisterWindow中,而不是让它作为独立应用运行。具体修改如下:

1. 保留a.py的结构(无需大幅修改)

a.py里的SplashApp可以保留,方便你单独调试LandingScreen,它不会影响被导入时的使用:

# a.py文件
import kivy
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.label import Label

class LandingScreen(FloatLayout):
    def __init__(self, **kwargs):
        super(LandingScreen, self).__init__(**kwargs)
        self.btn1=Button(text='button1 ', size_hint=(0.5, 0.5), on_press=self.click_b1)
        self.btn2=Button(text='button2', size_hint=(0.5, 0.5), on_press=self.click_b2)
        self.add_widget(self.btn1)
        self.add_widget(self.btn2)
    def click_b1(self, instance):
        pass
    def click_b2(self, instance):
        pass

class SplashApp(App):
    def build(self):
        return LandingScreen()

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

2. 修改b.py的RegisterWindow

把原来调用a.SplashApp().run()的代码,替换成直接添加LandingScreen作为RegisterWindow的子控件:

# 含Screen Manager的b.py文件
import a
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

class ScreenManagement(ScreenManager):
    def __init__(self, **kwargs):
        super(ScreenManagement, self).__init__(**kwargs)

class RegisterWindow(Screen):
    def __init__(self, **kwargs):
        super(RegisterWindow, self).__init__(**kwargs)
        # 替换掉原来的a.SplashApp().run(),直接添加LandingScreen作为子控件
        self.add_widget(a.LandingScreen())

class LoginWindow(Screen):
    def __init__(self, **kwargs):
        super(LoginWindow, self).__init__(**kwargs)
        self.btn2 = Button(text='Go', pos_hint={'center_x':0.5, 'center_y':0.5})
        self.add_widget(self.btn2)
        self.btn2.bind(on_press = self.screen_transition)
    def screen_transition(self, *args):
        self.manager.current = 'register'

class Application(App):
    def build(self):
        sm = ScreenManagement(transition=FadeTransition())
        sm.add_widget(LoginWindow(name='login'))
        sm.add_widget(RegisterWindow(name='register'))
        return sm

if __name__ == "__main__":
    Application().run()
额外优化建议
  • 我给LoginWindow里的按钮加了pos_hint让它居中显示,你可以根据自己的需求调整布局参数。
  • 拆分Kivy代码的正确思路是:把**独立的UI组件(如各种Layout、自定义Widget)**放到不同文件,主应用负责用ScreenManager统一管理这些组件的切换逻辑,而不是在组件内部启动新的App。这样既能拆分代码避免臃肿,又能保证应用的整体流程正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 13:17:49