Python/Kivy动态行垂直滚动条异常问题求助
Hey there! Let's fix that annoying extra spacing issue in your Kivy ScrollView. I've gone through your code and spotted a few key problems causing those gaps. Here's how to get your dynamic rows to stack neatly without extra space:
1. Fix the ScrollView Structure
Your current ScrollView wraps the Rows component in an unnecessary horizontal BoxLayout with a fixed height, which forces extra empty space. Instead, we'll make Rows the direct child of the ScrollView and let its height adapt to content:
Modified demo.kv ScrollView section:
ScrollView: Rows: id: rows size_hint_y: None height: self.minimum_height # Auto-adjust height to fit all rows
2. Clean Up the Row Layout
The top: 200 property on your first button was causing unwanted vertical offset, and we need to ensure each Row has a fixed, compact height:
Modified demo.kv
<Row>: size_hint_y: None height: 40 # Match the GridLayout's row height to avoid empty space GridLayout: cols: 2 row_force_default: True row_default_height: 40 spacing: 0 # Remove gap between buttons padding: 0 # Remove inner padding Button: text: root.button_text size_hint_x: None width: 100 # Fixed width for consistency Button: text: 'World 1' size_hint_x: 1 # Fill remaining space
3. Eliminate Row-to-Row Spacing
By default, BoxLayout adds small spacing between widgets. We'll disable this in the Rows class to make rows stack tightly:
Modified demo.py Rows class:
class Rows(BoxLayout): orientation = "vertical" row_count = 0 def __init__(self, **kwargs): super(Rows, self).__init__(**kwargs) self.spacing = 0 # Remove gap between rows self.add_row() def add_row(self): self.row_count += 1 self.add_widget(Row(button_text=str(self.row_count)))
Full Modified Code
demo.py
import kivy from kivy.uix.screenmanager import Screen from kivy.app import App from kivy.lang import Builder from kivy.core.window import Window from kivy.uix.boxlayout import BoxLayout from kivy.properties import StringProperty Window.clearcolor = (0.5, 0.5, 0.5, 1) Window.size = (500, 400) class user(Screen): def add_more(self): self.ids.rows.add_row() class Row(BoxLayout): button_text = StringProperty("") class Rows(BoxLayout): orientation = "vertical" row_count = 0 def __init__(self, **kwargs): super(Rows, self).__init__(**kwargs) self.spacing = 0 self.add_row() def add_row(self): self.row_count += 1 self.add_widget(Row(button_text=str(self.row_count))) class Test(App): def build(self): self.root = Builder.load_file('demo.kv') return self.root if __name__ == '__main__': Test().run()
demo.kv
<Button@Button>: font_size: 15 font_name: 'Verdana' <Label@Label>: font_size: 15 font_name: 'Verdana' <TextInput@TextInput>: font_size: 15 font_name: 'Verdana' padding_y: 3 <Row>: size_hint_y: None height: 40 GridLayout: cols: 2 row_force_default: True row_default_height: 40 spacing: 0 padding: 0 Button: text: root.button_text size_hint_x: None width: 100 Button: text: 'World 1' size_hint_x: 1 user: BoxLayout: orientation: "vertical" padding : 20, 5 BoxLayout: orientation: "horizontal" spacing: 10, 10 size: 450, 40 size_hint: None, None Label: size_hint_x: .2 text: "Test 1" text_size: self.size valign: 'bottom' halign: 'center' Label: size_hint_x: .8 text: "Test 2" text_size: self.size valign: 'bottom' halign: 'center' ScrollView: Rows: id: rows size_hint_y: None height: self.minimum_height BoxLayout: orientation: "horizontal" size_hint_x: .2 size_hint_y: .2 Button: text: "+Add More" on_press: root.add_more() BoxLayout: orientation: "horizontal" padding : 10, 5 spacing: 10, 10 size_hint: .5, .35 pos_hint: {'x': .25, 'y':.25} Button: text: 'Ok' Button: text: 'Cancel'
With these changes, your rows will stack tightly without extra spacing, and the ScrollView will correctly scroll when you add enough rows to exceed its visible area.
内容的提问来源于stack exchange,提问作者Veragi

