为什么 ScrollView 不能正常工作?

Why isn't the ScrollView working properly?

我基本上不知道为什么 ScrollView 不滚动

这里是 python 代码:

from kivy.app import App
from kivy.config import Config
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.properties import NumericProperty
from kivy.properties import ListProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import *
from kivy.uix.scrollview import ScrollView


class ScrollButton(Button):
    pass

class DropperScrollView(ScrollView):
    layout=ObjectProperty()

class MainWindow(FloatLayout):
    mainbox=ObjectProperty()
    dropper=ObjectProperty()
    mainbutton=ObjectProperty()
    dropper_button_1=ObjectProperty()
    dropper_button_2=ObjectProperty()
    dropper_button_3=ObjectProperty()
    dropper_button_4=ObjectProperty()
    scroll_list=ObjectProperty()

    def open_dropper(self,dt):
        self.dropper.open(self.mainbutton)

    def btn_1(self,a):
        if self.scroll_list.layout.children==[]:
            btn_1=ScrollButton(text='Button 1')
            btn_2=ScrollButton(text='Button 2')
            self.scroll_list.layout.add_widget(btn_1)
            self.scroll_list.layout.add_widget(btn_2)


class BioWikiaApp(App):
    ratio=1/7
    window_width=360
    window_height=640
    squared_ratio=NumericProperty(ratio)
    squared_dropper_size_hint=ListProperty([ratio,ratio*9/16])
    squared_dropper_size=ListProperty([window_width*ratio,window_height*ratio*9/16])
    def build(self):
        Window.size=(self.window_width,self.window_height)
        Window.clearcolor=(155/255,220/255,160/255,1)
        return MainWindow()


if __name__=='__main__':
    app=BioWikiaApp()
    app.run()

以及 kivy 文件:

#:import Clock kivy.clock.Clock
#:import App kivy.app.App
#:import Window kivy.core.window.Window
#:import NoTransition kivy.uix.screenmanager.NoTransition
<DropperScrollView>:
    layout:scroll_layout
    size_hint_x:app.squared_ratio
    pos_hint:{'x':app.ratio,'y':0}
    GridLayout:
        id:scroll_layout
        cols:1
        size_hint_y:None

<ScrollButton>:
    size_hint_y:None
    height:400

<MainWindow>:
    id:mainwindow
    mainbox:mainbox
    dropper:dropper
    dropper_button_1:dropper_button_1
    dropper_button_2:dropper_button_2
    dropper_button_3:dropper_button_3
    dropper_button_4:dropper_button_4
    mainbutton:mainbutton
    scroll_list:scroll_list
    BoxLayout:
        id:mainbox
        Label:
            text:'This will hold the title'
    Button:
        id:mainbutton
        text:'Home'
        size_hint:app.squared_dropper_size_hint[0],app.squared_dropper_size_hint[1]
        pos_hint:{'x':0,'y':1-app.squared_dropper_size_hint[1]}
        on_parent:
            dropper.dismiss()
            Clock.schedule_once(root.open_dropper,-1)
        on_release:dropper.open(self)
    DropDown:
        id:dropper
        dismiss_on_select:False
        on_select: mainbutton.text = '{}'.format(args[1])
        Button:
            id:dropper_button_1
            text:'1'
            size_hint_y:None
            height:mainbutton.height
            on_release:root.btn_1(self)
        Button:
            id:dropper_button_2
            text:'2'
            size_hint_y:None
            height:mainbutton.height
            on_release:root.btn_1(self)
        Button:
            id:dropper_button_3
            text:'3'
            size_hint_y:None
            height:mainbutton.height
            on_release:root.btn_1(self)
        Button:
            id:dropper_button_4
            text:'4'    
            size_hint_y:None
            height:mainbutton.height
            on_release:root.btn_1(self)
    DropperScrollView:
        id:scroll_list

虽然目前对我来说真正重要的是让这个该死的 ScrollView 滚动,但请随时纠正我可能做错的任何其他事情(比如让 Drop_Down List a child of the mainwindow 因为我否则无法正常工作)

非常感谢

解决方案

详情请参考示例

  1. DropDown 和 Popup 一样是一个特殊的小部件。不要尝试将其作为子项添加到任何其他小部件。如果这样做,DropDown 将像普通小部件一样处理,下拉列表将打开,即不会在后台关闭。在 kv 文件中,创建一个 dynamic class <CustomDropDown@DropDown>: 并向其添加小部件。
  2. ScrollView 中的按钮比 ScrollView 大,因为未指定 size_hint_y: None
  3. 将高度设置为最小高度,以便可以滚动。

ScrollView » Managing the Content Size and Position

layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
# Make sure the height is such that there is something to scroll.
layout.bind(minimum_height=layout.setter('height'))
for i in range(100):
    btn = Button(text=str(i), size_hint_y=None, height=40)
    layout.add_widget(btn)
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))

ScrollView » bar_width

bar_width

Width of the horizontal / vertical scroll bar. The width is interpreted as a height for the horizontal bar.

bar_width is a NumericProperty and defaults to 2.

例子

main.py

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.properties import ListProperty, NumericProperty, ObjectProperty


class ScrollButton(Button):
    pass


class DropperScrollView(ScrollView):
    layout = ObjectProperty(None)


class MainWindow(FloatLayout):
    mainbutton = ObjectProperty(None)
    scroll_list = ObjectProperty(None)

    def btn_1(self):
        if not self.scroll_list.layout.children:    # empty list
            btn_1 = ScrollButton(text='Button 1')
            btn_2 = ScrollButton(text='Button 2')
            self.scroll_list.layout.add_widget(btn_1)
            self.scroll_list.layout.add_widget(btn_2)


class BioWikiaApp(App):
    ratio = 1/7
    window_width = 360
    window_height = 640
    squared_ratio = NumericProperty(ratio)
    squared_dropper_size_hint = ListProperty([ratio, ratio*9/16])
    squared_dropper_size = ListProperty([window_width*ratio, window_height*ratio*9/16])

    def build(self):
        Window.size = (self.window_width, self.window_height)
        Window.clearcolor = (155/255, 220/255, 160/255, 1)
        return MainWindow()


if __name__ == '__main__':
    BioWikiaApp().run()

biowikia.kv

#:kivy 1.11.0
#:import Factory kivy.factory.Factory

<DropDownButton@Button>:
    size_hint_y: None
    height: app.root.mainbutton.height


<CustomDropDown@DropDown>:
    on_select: app.root.mainbutton.text = '{}'.format(args[1])

    DropDownButton:
        id: dropper_button_1
        text: '1'
        on_release:
            root.select(self.text)
            app.root.btn_1()

    DropDownButton:
        id: dropper_button_2
        text: '2'
        on_release:
            root.select(self.text)
            app.root.btn_1()

    DropDownButton:
        id: dropper_button_3
        text: '3'
        on_release:
            root.select(self.text)
            app.root.btn_1()

    DropDownButton:
        id: dropper_button_4
        text: '4'
        on_release:
            root.select(self.text)
            app.root.btn_1()


<DropperScrollView>:
    layout: scroll_layout
    size_hint: (app.squared_ratio, None)
    pos_hint: {'x': app.ratio, 'y': 0}

    bar_width: 10
    bar_color: 0, 1, 0, 1   # green
    bar_inactive_color: 1, 0, 0, 1   # red
    effect_cls: "ScrollEffect"
    scroll_type: ['bars']

    GridLayout:
        id: scroll_layout
        cols: 1
        size_hint_y: None
        height: self.minimum_height

<ScrollButton>:
    size_hint_y: None
    height: 400

<MainWindow>:
    mainbox: mainbox
    mainbutton: mainbutton
    scroll_list: scroll_list

    BoxLayout:
        id: mainbox

        Label:
            text:'This will hold the title'
    Button:
        id: mainbutton
        text: 'Home'
        size_hint: app.squared_dropper_size_hint[0], app.squared_dropper_size_hint[1]
        pos_hint: {'x':0, 'y': 1 - app.squared_dropper_size_hint[1]}
        on_release: Factory.CustomDropDown().open(self)

    DropperScrollView:
        id:scroll_list

输出