Kivy中TabbedPanel内嵌Screen切换提示无manager属性问题
报错根因
抛出AttributeError: 'TabbedTest' object has no attribute 'manager'是因为kv语法里root永远指向当前kv规则块的最外层组件。你在<TabbedTest>规则块内写root.manager,这里的root是TabbedTest类的实例,TabbedPanel本身没有内置manager属性,自然触发属性不存在的错误。
除此之外你的代码结构本身存在逻辑错误:你在Python代码里把ScreenManager和TabbedPanel作为平级组件都加到了外层FloatLayout,同时又在kv的TabbedPanelItem下单独声明了一个MainScreen实例,这个MainScreen根本不归你创建的self.sm管控,就算修掉属性报错,屏幕切换逻辑也无法正常运行。
修复步骤
- 移除Python代码中平级添加ScreenManager的逻辑,直接把ScreenManager作为TabbedPanelItem的子组件放在kv中,让所有需要在标签页内切换的Screen都归属同一个ScreenManager管理
- 把Screen内的按钮切换逻辑挪到对应Screen的kv规则块内,此时规则块内的
root才是Screen实例,可直接访问自带的manager属性获取所属的ScreenManager实例
修正后Python代码
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.tabbedpanel import TabbedPanel from kivy.uix.floatlayout import FloatLayout class TabbedTest(TabbedPanel): pass class MainScreen(Screen): pass class Firstscreen(Screen): pass class myapp(App): def build(self): root = FloatLayout() self.tabbedtest = TabbedTest() root.add_widget(self.tabbedtest) return root if __name__ == '__main__': myapp().run()
修正后kv代码(my.kv)
<TabbedTest> do_default_tab: False TabbedPanelItem: text: "test" ScreenManager: id: sm MainScreen: name: 'main' Firstscreen: name: 'first' <MainScreen>: BoxLayout: Button: text: 'first' on_press: root.manager.current = 'first' <Firstscreen>: BoxLayout: Label: text: "first" Button: text: 'Back to main' on_press: root.manager.current = 'main'
补充说明
如果需要在Python代码中操作标签页内的ScreenManager,直接通过self.tabbedtest.ids.sm即可获取对应实例,不需要额外给TabbedPanel类添加属性。注意不要重复实例化同一个Screen类,多个同名/同类的Screen实例互不归属,会导致切换逻辑异常。
内容的提问来源于stack exchange,提问作者maxnm47
相关产品推荐
相关产品推荐

