具有 3 个 ScrollView 布局的 Kivy ScrollView - 尝试像 Excel 中那样创建冻结窗格

Kivy ScrollView with 3 ScrollView Layouts - Trying to create freeze pane like in Excel

我在 Python

中使用 Kivy 库

我正在尝试将 3 个滚动布局组合在一起。基本上,一个副列表、一个 header 视图和一个主要 body window。旁边的列表应该只上下滚动。 header 应该只左右滚动,主 window 可以在两个轴上滚动。我已经完成了这么多,但主要 window 中的信息将链接到 header 和辅助列表中的信息,因此让它们独立滚动是行不通的。

我的目标是当主 window 滚动时,x 和 y 滚动值被传递到侧边菜单和 header 以便它们都在适当的方向一起滚动.我通读了 github 上的滚动视图代码,只是无法弄清楚我可以使用哪些属性来使其工作。我在想我可以将卷轴从一种布局传递到另一种布局!也许太简单了!!!

或者,也许我需要从 GridLayout 开始??

感谢任何意见

我目前的代码...py 文件

    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.config import Config
    from kivy.uix.stacklayout import StackLayout
    from kivy.uix.widget import Widget
    from kivy.uix.label import Label
    from datetime import datetime as dt
    from datetime import timedelta


    Config.set('graphics', 'width', '500')
    Config.set('graphics', 'height', '800')


    names = [str(x) for x in range (60)]


    end =dt.strptime((dt.today()+timedelta(days=1)).strftime("%d/%m/%Y")+ " "+ "00:01","%d/%m/%Y %H:%M" )
    result_time = "00:00"
    time =dt.strptime(dt.today().strftime("%d/%m/%Y")+ " "+ result_time,"%d/%m/%Y %H:%M" )
    segment = timedelta(minutes = 15)
    time_list = []

    while time<end:
        time_list.append(result_time)
        time += segment
        result_time = dt.strftime(time, "%H:%M")



    class TimeButton(Label):
        pass

    class BoxesLabel(Widget):
        pass

    class NameButton(Label):
        pass

    class Names(StackLayout):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            for x in names:
                btn = NameButton(text = x)
                self.add_widget(btn)

    class Times(StackLayout):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            for time in time_list:
                btn = TimeButton(text = time)
                self.add_widget(btn)


    class Boxes(StackLayout):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            for time in time_list:
                for name in names:
                    btn = BoxesLabel()
                    self.add_widget(btn)


    class MainWindow(BoxLayout):
        pass




    class TempApp(App):
        def build(self):
            return MainWindow()

    if __name__=="__main__":
        TempApp().run()



    

和 kv 文件

    <Layout>: #this just puts a box around all boxlayouts
        canvas.before:
            Color:
                rgba: 1,1,0,1
            Line:
                rectangle: (self.x, self.y, self.width, self.height)

    <NameButton>:
        size_hint_y: None
        size: dp(0),dp(50)

    <Names>:
        height: self.minimum_height
        padding: 10
        orientation: "lr-tb" 
        size_hint: 1, None
        size: 1, self.height

    <TimeButton>:
        size_hint: None, 1
        size: dp(50),0

    <Times>:
        width: dp(5000)
        orientation: "lr-tb"     
        size_hint: None, 1
        size: self.width, 1





    <BoxesLabel>:
        canvas.before:
            Color:
                rgba: 1,0,0,1
            Line:
                rectangle: (self.x, self.y, self.width, self.height)
        size_hint: None, None
        size: dp(50),dp(50)

    <Boxes>:
        size_hint: None, None
        width: dp(5000)
        height: self.minimum_height
        padding: 10
        orientation: "lr-tb"     



    <MainWindow>:
        orientation: "vertical"

        BoxLayout:  
            size_hint_y: None
            size_y: dp(150) 

            BoxLayout:
                size_hint_x: None
                size: dp(100),0

            ScrollView:
                BoxLayout:
                    width: dp(5000)#self.minimum_width     
                    size_hint: None, 1
                    size: self.width, 1
                    orientation: "vertical"
                    padding: dp(10)

                    BoxLayout:
                        Times:


        BoxLayout: 
            ScrollView:
                size_hint_x: None
                size: dp(100),0

                Names:

            ScrollView:

                Boxes:

所以在 6 小时后我终于搞定了,感谢

这是我使用的代码,只是将相关的 scroll_x 和 scroll_y 值绑定到彼此的滚动框!! PY 文件没有变化,只在 kv 文件中添加了几行!

这是更新后的 KV 文件

    <Layout>: #this just puts a box around all boxlayouts
        canvas.before:
            Color:
                rgba: 1,1,0,1
            Line:
                rectangle: (self.x, self.y, self.width, self.height)

    <NameButton>:
        size_hint_y: None
        size: dp(0),dp(50)

    <Names>:
        height: self.minimum_height
        padding: 10
        orientation: "lr-tb" 
        size_hint: 1, None
        size: 1, self.height

    <TimeButton>:
        size_hint: None, 1
        size: dp(50),0

    <Times>:
        width: dp(5000)
        orientation: "lr-tb"     
        size_hint: None, 1
        size: self.width, 1





    <BoxesLabel>:
        canvas.before:
            Color:
                rgba: 1,0,0,1
            Line:
                rectangle: (self.x, self.y, self.width, self.height)
        size_hint: None, None
        size: dp(50),dp(50)

    <Boxes>:
        size_hint: None, None
        width: dp(5000)
        height: self.minimum_height
        padding: 10
        orientation: "lr-tb"     



    <MainWindow>:

        orientation: "vertical"

        BoxLayout:  
            size_hint_y: None
            size_y: dp(150) 

            BoxLayout:
                size_hint_x: None
                size: dp(100),0

            ScrollView:
                id: _Header_Scroll
                _Boxes_Scroll: _Boxes_Scroll
                scroll_x: self._Boxes_Scroll.scroll_x

                BoxLayout:
                    width: dp(5000)#self.minimum_width     
                    size_hint: None, 1
                    size: self.width, 1
                    orientation: "vertical"
                    padding: dp(10)

                    BoxLayout:
                        Times:


        BoxLayout: 
            ScrollView:
                id: _Names_Scroll
                _Boxes_Scroll: _Boxes_Scroll
                scroll_y: self._Boxes_Scroll.scroll_y

                size_hint_x: None
                size: dp(100),0

                Names:

            ScrollView:
                id: _Boxes_Scroll
                _Names_Scroll: _Names_Scroll
                scroll_y: self._Names_Scroll.scroll_y

                _Header_Scroll: _Header_Scroll
                scroll_x: self._Header_Scroll.scroll_x

                Boxes: