如何在 Kivy 中使用多个拆分器?

How to use several splitters in Kivy?

我想在一个屏幕中使用两个分离器,这样用户就可以使用 3 个部分中的任何一个来填满整个屏幕(但要留出一些空间来显示分离器)。

我试过这样做(见下面的代码),但是当我将第 3 部分缩小到最小值然后尽可能放大第 1 部分时,第 3 部分消失了,这不是我想要的行为(我'我希望它对所有 3 个部分都是对称的)。

有人知道吗?

BoxLayout:
id: all
min_view_size: sp(30)
strip_size: sp(13)

Splitter:
    sizable_from: 'right'
    strip_size: all.strip_size
    max_size: all.width - (all.min_view_size + all.strip_size)*2
    min_size: all.min_view_size + all.strip_size

    Label:
        text: '1'

Splitter:
    sizable_from: 'right'
    strip_size: all.strip_size
    max_size: all.width - (all.min_view_size + self.strip_size)*2
    min_size: all.min_view_size + self.strip_size

    Label:
        text: '2'

BoxLayout:
    max_size: all.width - (all.min_view_size + all.strip_size)*2
    min_size: all.min_view_size
    Label:
        text: '3'

经过一些调整后,这里是 2 个水平分离器的工作示例,因此它们之间的部分具有最小尺寸:

BoxLayout:
    id: all
    min_view_size: sp(30)
    strip_size: sp(13)

Splitter:
    id: splitter1
    sizable_from: 'right'
    strip_size: all.strip_size
    max_size: all.width - (all.min_view_size + all.strip_size)*2
    min_size: all.min_view_size + all.strip_size

    Label:
        text: '1'

Splitter:
    id: splitter2
    sizable_from: 'right'
    strip_size: all.strip_size
    max_size: (all.width - splitter1.width) - (all.min_view_size + self.strip_size)
    min_size: all.min_view_size + self.strip_size

    Label:
        text: '2'

BoxLayout:
    Label:
        text: '3'

诀窍是让第二个拆分器的 min_size 规则取决于第一个拆分器的大小。

编辑:

这里是当 window 为 narrow/wide 时自动调整方向:

BoxLayout:
    id: all
    min_view_size: sp(30)
    strip_size: sp(13)
    orientation: 'vertical' if self.width < self.height else 'horizontal'
    vertical: self.orientation == 'vertical'
    bigger_size: self.height if self.vertical else self.width
    default_part_size: (self.bigger_size - self.strip_size*2)/3

    # Reset part sizes when orientation changes
    on_vertical:
        if args[1]: (splitter1.height, splitter2.height) = (self.default_part_size, self.default_part_size)
        if not args[1]: (splitter1.width, splitter2.width) = (self.default_part_size, self.default_part_size)

Splitter:
    id: splitter1
    strip_size: all.strip_size
    max_size: all.bigger_size - (all.min_view_size + all.strip_size)*2
    min_size: all.min_view_size + all.strip_size
    sizable_from: 'bottom' if all.vertical else 'right'
    size_hint: (1, None) if all.vertical else (None, 1)
    size: (all.width, all.default_part_size) if all.vertical else (all.default_part_size, all.height)

    BoxLayout:
        Button:
            text: '1'

Splitter:
    id: splitter2
    strip_size: all.strip_size
    splitter1_bigger_size: splitter1.height if all.vertical else splitter1.width
    max_size: (all.bigger_size - self.splitter1_bigger_size) - (all.min_view_size + self.strip_size)
    min_size: all.min_view_size + self.strip_size
    sizable_from: 'bottom' if all.vertical else 'right'
    size_hint: (1, None) if all.vertical else (None, 1)
    size: (all.width, all.default_part_size) if all.vertical else (all.default_part_size, all.height)

    BoxLayout:    
        Button:
            text: '2'

BoxLayout:
    Button:
        text: '3'