Kivy ScreenManager问题求助:Python3下实现屏幕切换报错
解决Kivy ScreenManager纯Python实现的问题
嘿,我来帮你搞定这个ScreenManager的问题!先拆解下你代码里的几个关键错误,然后一步步改成纯Python实现的屏幕切换功能。
首先说你遇到的报错原因
你写的BanditKing类同时继承了App和ScreenManager,这是完全错误的。Kivy的App类本身不需要继承ScreenManager,多重继承在这里触发了初始化逻辑冲突,就是你看到的TypeError: object.__init__() takes no parameters错误——两个父类的初始化方法打架了。
纯Python实现ScreenManager的核心要点
- 每个要切换的屏幕必须是继承
Screen的类,而不是直接用FloatLayout ScreenManager需要实例化(加括号()),不能只引用类- 把各个Screen实例添加到ScreenManager中,通过
name属性标识每个屏幕 - 切换屏幕时,通过
Screen的manager属性访问ScreenManager,修改current属性为目标屏幕的name
修正后的完整代码
""" Python 3.6.4 Kivy 1.10.0 Combines various .py files and allows the game to run. """ __author__ = "RidiculousName" __date__ = "Jan. 2018" import sys from kivy.app import App from kivy.config import Config from kivy.uix.image import Image from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.uix.screenmanager import ScreenManager, Screen # 主菜单屏幕:继承Screen class MainMenu(Screen): def __init__(self, **kwargs): super(MainMenu, self).__init__(**kwargs) # 创建FloatLayout作为屏幕的根布局 layout = FloatLayout() # 初始化控件 background = Image(source="Img\\BG.png", pos=(0, 0)) start_button = Button(pos=(25, 75), background_normal="Img\\Start.png", background_down="Img\\Start_Down.png", size_hint=(.1, .1)) load_button = Button(pos=(225, 75), background_normal="Img\\Load.png", background_down="Img\\Load_Down.png", size_hint=(.1, .1)) options_button = Button(pos=(425, 75), background_normal="Img\\Options.png", background_down="Img\\Options_Down.png", size_hint=(.15, .1)) quit_button = Button(pos=(708, 75), background_normal="Img\\Quit.png", background_down="Img\\Quit_Down.png", size_hint=(.1, .1)) # 绑定事件 quit_button.bind(on_press=sys.exit) start_button.bind(on_press=self.go_to_game) # 绑定切换到游戏屏幕的方法 # 添加控件到布局 layout.add_widget(background) layout.add_widget(start_button) layout.add_widget(load_button) layout.add_widget(options_button) layout.add_widget(quit_button) # 把布局添加到Screen中 self.add_widget(layout) def go_to_game(self, instance): # 通过manager属性获取ScreenManager,切换到game屏幕 self.manager.current = "game" # 游戏测试屏幕:同样继承Screen class GameScreen(Screen): def __init__(self, **kwargs): super(GameScreen, self).__init__(**kwargs) layout = FloatLayout() back_button = Button(text="回到主菜单", pos=(50, 50), size_hint=(.2, .1)) back_button.bind(on_press=self.go_back_to_menu) layout.add_widget(back_button) self.add_widget(layout) def go_back_to_menu(self, instance): # 切换回主菜单屏幕 self.manager.current = "main_menu" # 主App类:只需要继承App,不用继承ScreenManager class BanditKing(App): def build(self): # 实例化ScreenManager sm = ScreenManager() # 添加各个屏幕,指定name属性用于切换 sm.add_widget(MainMenu(name="main_menu")) sm.add_widget(GameScreen(name="game")) # 设置窗口属性 self.title = "Bandit King" self.icon = "Window_Icon.png" return sm def main(): Config.set("graphics", "width", "1600") Config.set("graphics", "height", "900") Config.write() BanditKing().run() if __name__ == "__main__": main()
额外说明
- 每个
Screen实例都自带manager属性,指向它所属的ScreenManager,所以不用手动传递 - 如果你需要更多屏幕,只需要创建新的
Screen子类,添加到ScreenManager里,然后通过self.manager.current = "屏幕name"切换 - 你原来的控件布局逻辑完全保留了,只是把FloatLayout放到了Screen里面,符合Kivy的屏幕管理规范
内容的提问来源于stack exchange,提问作者LuminousNutria
相关产品推荐
相关产品推荐

