Kivy/Python:嵌套规则布局下子部件无法显示问题
Kivy自定义Screen作为ScreenManager子部件时界面空白问题
我开发了一个用ScreenManager管理界面的简单Kivy应用。当把自定义的myScreen作为应用根部件时一切正常,但将它作为子部件放入MyScreenManager后,界面完全空白,所有子部件都不显示。
相关代码
testScreenManager.py
from kivy.app import App from kivy.uix.textinput import TextInput from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.graphics.vertex_instructions import Rectangle from kivy.uix.screenmanager import ScreenManager, Screen class MyScreenManager(ScreenManager): pass class myScreen(Screen): pass class myNavBoxes(BoxLayout): pass class myApp(App): def build(self): return MyScreenManager() if __name__ == "__main__": myApp().run()
my.kv
<MyScreenManager>: canvas.before: Rectangle: pos: self.pos size: self.size myScreen: <myScreen>: BoxLayout: orientation: 'vertical' size_hint: 0.8, 0.3 pos_hint: {'x':0.1, 'y':0.5} TextInput: id: username hint_text: 'Username' font_size: '20sp' myNavBoxes: <myNavBoxes>: orientation: 'horizontal' size_hint: 1, .2 pos_hint: {'x':.0, 'y':.0} Button: id: navButtonLogin text: 'Login' font_size: '15sp' size_hint_y: None
测试情况
运行后仅显示空白矩形,无任何部件。但如果不使用自定义myScreen,直接用基类Screen,子部件就能正常显示:
<MyScreenManager>: canvas.before: Rectangle: pos: self.pos size: self.size Screen: BoxLayout: orientation: 'vertical' size_hint: 0.8, 0.3 pos_hint: {'x':0.1, 'y':0.5} TextInput: id: username hint_text: 'Username' font_size: '20sp' myNavBoxes: <myNavBoxes>: orientation: 'horizontal' size_hint: 1, .2 pos_hint: {'x':.0, 'y':.0} Button: id: navButtonLogin text: 'Login' font_size: '15sp' size_hint_y: None
问题原因及解决方法
原因
Kivy的Screen部件默认依赖一个FloatLayout作为根容器来管理子部件的布局。使用基类Screen时,Kivy会自动创建这个容器;但自定义Screen类时,必须显式声明这个容器,否则直接添加的子部件无法被正确布局显示。
解决方法
方法1:在KV规则中为自定义Screen添加FloatLayout容器
修改my.kv中<myScreen>的规则,将所有子部件放入FloatLayout内:
<myScreen>: FloatLayout: BoxLayout: orientation: 'vertical' size_hint: 0.8, 0.3 pos_hint: {'x':0.1, 'y':0.5} TextInput: id: username hint_text: 'Username' font_size: '20sp' myNavBoxes:
方法2:在Python代码中为自定义Screen添加FloatLayout容器
修改testScreenManager.py中的myScreen类,在初始化时添加默认布局容器:
class myScreen(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) # 添加默认的FloatLayout容器 from kivy.uix.floatlayout import FloatLayout self.layout = FloatLayout() self.add_widget(self.layout)
(如果用这种方法,KV中<myScreen>的子部件需要指定添加到这个layout上,或者直接在KV里用self.layout作为父容器)
内容的提问来源于stack exchange,提问作者Wamseln
相关产品推荐
相关产品推荐

