如何在含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
相关产品推荐
相关产品推荐

