Python Kivy选择类应用开发:解决隐藏控件残留空白空间问题
Fixing Kivy Widget Visibility & Layout Spacing Issues
Hey Batuhan! Let's get your layered widget display working properly. The issues you're seeing—residual blank space and widgets still showing even with height: 0dp—come from two main problems: unclipped child widgets and layout space not being fully collapsed when hidden. Here's how to fix it:
Key Fixes to Implement
- Correct the padding typo: You wrote
padinginstead ofpaddingin your BoxLayouts, which can cause unexpected spacing. - Add
clip_to_self: True: This ensures child widgets don't draw outside their parent's bounds (the reason content was visible even withheight: 0dp). - Toggle
size_hint_yalongside height: Settingsize_hint_y: 0when hidden tells the parent layout to allocate 0 vertical space, eliminating blank gaps.
Modified Code
main.py (cleaned-up version)
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.popup import Popup from kivy.uix.label import Label from kivy.lang import Builder from kivy.properties import BooleanProperty class MainWindow(Screen): def btn(self): popup = Popup(content=Label(text='Wrong Password'), size_hint=(None, None), size=(200, 200)) popup.bind(on_touch_down=popup.dismiss) popup.open() class SecondWindow(Screen): isShownMenu = BooleanProperty(True) # Hidden by default bisShownMenu = BooleanProperty(True) # Hidden by default class WindowManager(ScreenManager): pass kv = Builder.load_file("my.kv") class MyMainApp(App): def build(self): return kv if __name__== "__main__": MyMainApp().run()
my.kv (adjusted visibility logic)
WindowManager: MainWindow: SecondWindow: <ScrollViewExample@ScrollView>: SecondWindow: size_hint: 1, None height: self.minimum_height <Button>: size_hint: .35 , 1 height: "20dp" width: "20dp" pos_hint: {"center_x": .5} <MainWindow>: name:"main" BoxLayout: canvas.before: Rectangle: pos: self.pos size: self.size orientation: "vertical" Image: source:"vgs.png" size_hint: 1, None height: "110dp" allow_stretch: True keep_ratio: False AnchorLayout: anchor_x:"center" anchor_y:"center" BoxLayout: orientation: "vertical" spacing: "10dp" size_hint: .8,.3 BoxLayout: orientation: "horizontal" Label: text: "Username:" color: 0,0,0,1 TextInput: id: username text: "***" multiline: False BoxLayout: orientation: "horizontal" Label: text: "Password:" color: 0,0,0,1 TextInput: id: password text: "***" multiline: False BoxLayout: CheckBox: color: 0,0,0,1 Label: text: "Remember me" color: 0,0,0,1 Button: size_hint: .35 , 1 text: "Login" pos_hint: {"center_x": .5} on_release: app.root.current= "second" root.manager.transition.direction="left" <SecondWindow>: name:"second" ScrollView: GridLayout: cols:1 height: self.minimum_height row_default_height: "60dp" size_hint_y: None spacing:"10dp" canvas.before: Rectangle: pos: self.pos size: self.size Image: source:"vgs.png" size_hint: 1, None height: "110dp" allow_stretch: True keep_ratio: False BoxLayout: padding:"10dp" # Fixed typo spacing:"10dp" orientation: "vertical" BoxLayout: orientation: "horizontal" Label: text:"Solid Content:" color: 0,0,0,1 TextInput: text:"enter %" color: 0,0,0,1 BoxLayout: orientation: "horizontal" Label: text:"Pressure:" color: 0,0,0,1 TextInput: text:"enter BAR" color: 0,0,0,1 Button: text:" Model Selection" height: "20dp" width: "20dp" Button: text:" Screen Selection" Button: text:"Rotor Selection" Button: text:"Motor & Reduction Selection" Button: text:"Calculate Selections" on_press: root.isShownMenu = not root.isShownMenu # Calculation Results Section BoxLayout: padding:"10dp" # Fixed typo spacing:"10dp" size_hint_y: 0 if root.isShownMenu else None height: "0dp" if root.isShownMenu else "80dp" opacity: 0 if root.isShownMenu else 1 clip_to_self: True orientation: "vertical" BoxLayout: orientation:"horizontal" Label: text:"Calculated Flow:" color: 0,0,0,1 Label: text:"enter %" color: 0,0,0,1 BoxLayout: orientation:"horizontal" Label: text:"Calculated Pressure:" color: 0,0,0,1 Label: text:"00000" color: 0,0,0,1 BoxLayout: orientation:"horizontal" Label: text:"Fibre Lenght:" color: 0,0,0,1 Label: text:"000000" color: 0,0,0,1 Button: on_press: root.bisShownMenu = not root.bisShownMenu text:"Confirm" # New Option Sections BoxLayout: size_hint_y: 0 if root.bisShownMenu else None height: "0dp" if root.bisShownMenu else "80dp" opacity: 0 if root.bisShownMenu else 1 clip_to_self: True orientation:"horizontal" Label: text:"cutter head material" color: 0,0,0,1 Button: text:"1.secim" Button: text:"2.secim" Button: text:"3.secim" Button: text:"4.secim" BoxLayout: size_hint_y: 0 if root.bisShownMenu else None height: "0dp" if root.bisShownMenu else "80dp" opacity: 0 if root.bisShownMenu else 1 clip_to_self: True orientation:"horizontal" Label: text:"screen material" color: 0,0,0,1 Button: text:"1.secim" Button: text:"2.secim" Button: text:"3.secim" Button: text:"4.secim" BoxLayout: size_hint_y: 0 if root.bisShownMenu else None height: "0dp" if root.bisShownMenu else "80dp" opacity: 0 if root.bisShownMenu else 1 clip_to_self: True orientation:"horizontal" Label: text:"blade material" color: 0,0,0,1 Button: text:"1.secim" Button: text:"2.secim" Button: text:"3.secim" Button: text:"4.secim" BoxLayout: size_hint_y: 0 if root.bisShownMenu else None height: "0dp" if root.bisShownMenu else "80dp" opacity: 0 if root.bisShownMenu else 1 clip_to_self: True orientation:"horizontal" Label: text:"pot material" color: 0,0,0,1 Button: text:"1.secim" Button: text:"2.secim" Button: text:"3.secim" Button: text:"4.secim" Button: size_hint: .35 , 1 text: "Back to Login" pos_hint: {"center_x": .5} on_release: app.root.current= "main" root.manager.transition.direction="right"
Why This Works
clip_to_self: True: This clips any child content that would draw outside the parent widget's bounds. So when the parent's height is set to 0, nothing from the children is visible.size_hint_y: 0: When hidden, this tells the GridLayout parent to allocate 0 vertical space for the widget, so no blank gaps are left in the interface.- Combined bindings: Toggling
size_hint_y,height, andopacityensures the widget is completely hidden (no space, no visible content) when the BooleanProperty isTrue, and fully visible when it'sFalse.
Now your workflow should work as expected:
- User fills in initial options and clicks "Calculate Selections" → calculation results appear (no blank space before).
- User clicks "Confirm" → the new material options appear, with no residual space from the hidden sections.
内容的提问来源于stack exchange,提问作者Batuhan Karakaya
相关产品推荐
相关产品推荐

