【问题标题】:How can I make my horizontal scroll view in Kivy centered on the screen?如何使 Kivy 中的水平滚动视图以屏幕为中心?
【发布时间】:2020-04-12 07:51:49
【问题描述】:

我正在尝试在 Kivy (Python) 中创建一个水平滚动视图,该视图将显示一个您可以滚动浏览的图像(目前为按钮)。我已经能够弄清楚如何进行水平滚动视图,但我似乎无法弄清楚我在屏幕上做错了什么。这是我目前所拥有的:

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout

class MyGrid(GridLayout):
    def __init__(self, **kwargs):
        super(MyGrid, self).__init__(**kwargs)
        self.rows = 1
        self.spacing=50
        self.size_hint=(None, .5)
        self.bind(minimum_width=self.setter('width'))

class ScrollViewApp(App):
    def build(self):
        scroll = ScrollView( size_hint=(1,1), do_scroll_x=True, do_scroll_y=False )
        grid = MyGrid()
        for i in range(60):
            grid.add_widget(Button(text='#00' + str(i),size=(100,100), size_hint=(1,1)))
        scroll.add_widget(grid)
        return scroll

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

我查看了文档,我认为它与 pos_hint 有关:https://kivy.org/doc/stable/api-kivy.uix.widget.html?highlight=pos_hint#kivy.uix.widget.Widget.pos_hint

我尝试添加:

self.pos={'center_y':1}

在我的 MyGrid() 类中,但没有任何改变。不管我在center_y后面放什么值,我的网格中包含的ScrollView仍然出现在屏幕的顶部,而不是中途居中。我也尝试过调整 ScrollViewApp() 类中的内容,使用

scroll.pos={'center_y':1}

也是。我似乎无法弄清楚我做错了什么。有人对我在这里不理解的内容有任何想法吗?我觉得我很接近了!!!

编辑:

我试图让按钮居中,但也可以通过拖动按钮周围的黑色空间来滚动。在下图中,您可以看到按钮下方有一堆黑色空间。我可以单击一个按钮或这个黑色空间并水平滚动。我只需要在按钮居中的情况下发生这种情况!

【问题讨论】:

    标签: python python-3.x kivy


    【解决方案1】:

    布局的行为与您所说的一样。
    您有一个 ScrollView 作为根小部件,并在其中放入具有 size_hint_y = 0.5Grid

    它占用父小部件高度的一半,即占用整个窗口高度。
    使Grid 居中的一种方法是在其上方和下方放置一些垫片,但这是不可能的,因为ScrollView 只接受一个小部件作为内容。

    所以,一种解决方案是......

    • Grid 拥有ScrollView 的全高
    • 在另一个布局中添加ScrollView(例如BoxLayout
    • 最后,添加两个小部件以将ScrollView 强制居中。
    class MyGrid(GridLayout):
        def __init__(self, **kwargs):
            super(MyGrid, self).__init__(**kwargs)
            self.rows = 1
            self.spacing = 50
            self.size_hint = (None, 1)
            self.bind(minimum_width=self.setter('width'))
    
    
    class ScrollViewApp(App):
        def build(self):
            base = BoxLayout(orientation="vertical", size_hint=(1, 1))
            base.add_widget(Widget(size_hint_y=.3))
            scroll = ScrollView(size_hint=(1, .4), do_scroll_x=True, do_scroll_y=False)
            grid = MyGrid()
            for i in range(60):
                grid.add_widget(
                    Button(text='#00' + str(i), size=(100, 100), size_hint=(1, 1)))
            scroll.add_widget(grid)
            base.add_widget(scroll)
            base.add_widget(Widget(size_hint_y=.3))
            return base
    
    
    if __name__ == '__main__':
        ScrollViewApp().run()
    

    另一种方法是......

    • ScrollView 放入FloatLayout
    • 并使用pos_hint 定位它
    class MyGrid(GridLayout):
        def __init__(self, **kwargs):
            super(MyGrid, self).__init__(**kwargs)
            self.rows = 1
            # self.spacing = 50
            self.size_hint = (None, 1)
            self.bind(minimum_width=self.setter('width'))
    
    
    class ScrollViewApp(App):
        def build(self):
            base = FloatLayout(size_hint=(1, 1))
            scroll = ScrollView(size_hint=(1, .4), do_scroll_x=True, do_scroll_y=False,
                                pos_hint={"center_y": .5})
            grid = MyGrid()
            for i in range(60):
                grid.add_widget(
                    Button(text='#00' + str(i), width=100, size_hint=(None, 1)))
            scroll.add_widget(grid)
            base.add_widget(scroll)
            return base
    
    
    if __name__ == '__main__':
        ScrollViewApp().run()
    

    编辑:

    好的。问题更新后,这是一种居中并使用黑条滚动的方法:

    Builder.load_string("""
    <BaseWidget>:
        ScrollView:
            do_scroll_y: False
            BoxLayout:
                orientation: "vertical"
                size_hint_x: None
                width: self.minimum_width
                Widget:
                    size_hint_y: .3
                GridLayout:
                    id: grid
                    rows: 1
                    size_hint_y: .4
                    size_hint_x: None
                    width: self.minimum_width
                Widget:
                    size_hint_y: .3
    """)
    
    
    class BaseWidget(FloatLayout):
        pass
    
    
    class ScrollViewApp(App):
        def build(self):
            base = BaseWidget()
            for i in range(60):
                base.ids.grid.add_widget(Button(text='#00' + str(i),
                                                width=100, size_hint_x=None))
            return base
    
    
    if __name__ == '__main__':
        ScrollViewApp().run()
    

    它使用kv_lng 来创建布局,因为我觉得它更容易看。
    对于“仅限 Python”的代码,您可以使用以下代码:

    class MyGrid(GridLayout):
        def __init__(self, **kwargs):
            super(MyGrid, self).__init__(**kwargs)
            self.rows = 1
            self.size_hint = None, .4
            self.bind(minimum_width=self.setter('width'))
    
    
    class MyBox(BoxLayout):
        def __init__(self, **kwargs):
            super(MyBox, self).__init__(**kwargs)
            self.orientation = "vertical"
            self.size_hint_x = None
            self.bind(minimum_width=self.setter('width'))
    
    
    class ScrollViewApp(App):
        def build(self):
            base = FloatLayout()
            grid = MyGrid()
            box = MyBox()
            box.add_widget(Widget(size_hint_y=.3))
            box.add_widget(grid)
            box.add_widget(Widget(size_hint_y=.3))
            for i in range(60):
                grid.add_widget(Button(text='#00' + str(i), width=100, size_hint_x=None))
            scroll = ScrollView(do_scroll_y=False, pos_hint={"center_y": .5})
            scroll.add_widget(box)
            base.add_widget(scroll)
            return base
    
    
    if __name__ == '__main__':
        ScrollViewApp().run()
    

    【讨论】:

    • 非常感谢您的回复!您的示例确实使按钮居中,但我不能使用按钮周围的黑色空间来水平滚动。我怎么能调整你的第二个例子来完成这个?抱歉,即使您回答了我的问题,我在原始帖子中也没有充分传达我的要求!我已经编辑了我的原始问题以反映这种需求。
    • 非常感谢@noEmbryo!您的代码是我正在寻找的答案。我还能够更多地了解如何使用 Kivy。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多