Kivy - 如何调整嵌入式锚布局的大小?

Kivy - How to Size Embedded Anchor Layouts?

我想在 .kv 文件中构建以下简单设计。

它由三部分组成:

这三个部分本身包含在一个 AnchorLayout 中。

我尝试将此设计转化为 .kv 文件,如下所示。

#:kivy 1.11.1

<Example>:
    anchor_x: "center"
    anchor_y: "center"

    AnchorLayout:
        anchor_x: "left"
        anchor_y: "top"
        size_hint: (0.2, 0.75)

        GridLayout:
            cols: 3
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"

    AnchorLayout:
        anchor_x: "right"
        anchor_y: "top"
        size_hint: (0.8, 0.75)

        BoxLayout:
            orientation: "vertical"
            Label:
                text: "HELLO..."
            Label:
                text: "WORLD..."

    AnchorLayout:
        anchor_x: "left"
        anchor_y: "bottom"
        size_hint: (1, 0.25)

        Label:
            text: "FOOTER"

以防万一,这也是我的 .py 文件的代码。

# Importing Kivy
import kivy
kivy.require("1.11.1")

# Importing kivy libraries
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.lang import Builder


# Importing external libraries


# Import kv files
Builder.load_file("example.kv")


# Root widget of the application
class Example(AnchorLayout):
    pass


# Application class
class TestApp(App):
    def build(self, **kwargs):
        return Example()

# Launch the application
if __name__=="__main__":
    app = TestApp()
    app.run()

输出与我预期的不一样,如下图所示:

我不明白。因为 AnchorLayout 是 Widget class 的子 class 并且它本身包含在 Layout 中,所以它的 size_hint 属性 应该能让我定义它的大小。

我在这里错过了什么?提前致谢!

Example class 更改为扩展 FloatLayout 而不是 AnchorLayout 允许对其子项进行更多控制。更改为 Example 后,kv 看起来更像您想要的:

<Example>:
    AnchorLayout:
        anchor_x: "center"
        anchor_y: "top"
        size_hint: (0.2, 0.75)
        pos_hint: {'x':0, 'top':1}

        GridLayout:
            cols: 3
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"

    AnchorLayout:
        anchor_x: "center"
        anchor_y: "top"
        size_hint: (0.8, 0.75)
        pos_hint: {'right':1, 'top':1}

        BoxLayout:
            orientation: "vertical"
            Label:
                text: "HELLO..."
            Label:
                text: "WORLD..."

    AnchorLayout:
        anchor_x: "center"
        anchor_y: "bottom"
        size_hint: (1, 0.25)
        pos_hint: {'x':0, 'y':0}

        Label:
            text: "FOOTER"

问题 - 以设计为中心

设计位于中心。

根本原因

根是 AnchorLayoutanchor_xanchor_y 的值为 'center'。因此,它的所有子节点(AnchorLayouts)都相对于根节点放置。

下面是您的设计视图,使用不同的颜色进行可视化。

AnchorLayout

AnchorLayout 将其子项与边框(上、下、左、右)或中心对齐。

解决方案

您的设计有三种可能的解决方案。首选方法1.

方法 1 - 否 AnchorLayouts

此方法将所有 AnchorLayout 替换为 BoxLayout。它减少了一个 AnchorLayout 小部件,这使应用程序的资源效率更高,即使用更少的内存并且应用程序更小。

片段 - 方法 1

<Example>:
    orientation: 'vertical'

    BoxLayout:
        ...
        GridLayout:    # left box
            ...
        BoxLayout:    # right box
            ...
    BoxLayout:    # footer
        ...

方法 2 - BoxLayout 作为 root

此方法用 BoxLayout 替换根小部件并重新对齐左侧框。

片段 - 方法 2

<Example>:
    orientation: 'vertical'

    AnchorLayout:
        ...
        GridLayout:    # left box
            ...
        AnchorLayout:    # right box
            ...
    AnchorLayout:    # footer
        ...

方法三

此方法添加一个 BoxLayout 作为根的子项,其余的 AnchorLayout 作为 BoxLayout.

的子项

片段 - 方法 3

<Example>:
    anchor_x: "center"
    anchor_y: "center"

    BoxLayout:
        orientation: 'vertical'

        AnchorLayout:
            ...
            GridLayout:    # left box
                ...
            AnchorLayout:    # right box
                ...
        AnchorLayout:    # footer
            ...

例子

方法 1 - 否 AnchorLayouts

main.py

from kivy.base import runTouchApp
from kivy.lang import Builder

runTouchApp(Builder.load_string("""

BoxLayout:
    orientation: 'vertical'

    BoxLayout:
        size_hint: 1, 0.75

        GridLayout:
            size_hint: 0.2, 1

            canvas.before:
                Color:
                    rgba: 1, 0, 0, 1
                Rectangle:
                    size: self.size
                    pos: self.pos

            cols: 3
            row_force_default: True
            row_default_height: 40

            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"            

        BoxLayout:
            orientation: 'vertical'

            canvas.before:
                Color:
                    rgba: 0, 1, 0, 1
                Rectangle:
                    size: self.size
                    pos: self.pos

            Label:
                text: "HELLO..."
            Label:
                text: "WORLD..."


    BoxLayout:
        size_hint: 1, 0.25

        canvas.before:
            Color:
                rgba: 0, 0, 1, 1
            Rectangle:
                size: self.size
                pos: self.pos

        Label:
            text: "FOOTER"

"""))

输出:方法 1 - 否 AnchorLayouts

方法 2 - BoxLayout 作为 root

main.py

from kivy.base import runTouchApp
from kivy.lang import Builder

runTouchApp(Builder.load_string("""

BoxLayout:
    orientation: 'vertical'

    AnchorLayout:
        size_hint: 1, 0.75
        anchor_x: 'left'
        anchor_y: 'top'

        GridLayout:
            size_hint: 0.2, 1

            canvas.before:
                Color:
                    rgba: 1, 0, 0, 1
                Rectangle:
                    size: self.size
                    pos: self.pos

            cols: 3
            row_force_default: True
            row_default_height: 40

            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"
            Button:
                text: "X"            

        AnchorLayout:
            anchor_x: 'right'
            anchor_y: 'top'

            BoxLayout:
                orientation: 'vertical'
                size_hint: 0.8, 1

                canvas.before:
                    Color:
                        rgba: 0, 1, 0, 1
                    Rectangle:
                        size: self.size
                        pos: self.pos

                Label:
                    text: "HELLO..."
                Label:
                    text: "WORLD..."


    AnchorLayout:
        size_hint: 1, 0.25
        anchor_x: 'left'
        anchor_y: 'bottom'

        canvas.before:
            Color:
                rgba: 0, 0, 1, 1
            Rectangle:
                size: self.size
                pos: self.pos

        Label:
            text: "FOOTER"

"""))

输出:方法 2 - BoxLayout 作为 root