为什么 none Kivy 的布局按预期工作?

Why none of Kivy's layouts work as expected?

这是我想要完成的,应该很简单:标签中的 header 文本,下面列出了一些垂直按钮并嵌套在右边

初审:

#:kivy 1.9.0


<SubjectButton@Button>:

  size_hint: None, None
  size: 40, 160

BoxLayout:

  orientation: "vertical"

  Label:
    text: "Choose Subject:"
    font_size: "16sp"
    bold: True
    halign: "left"


  BoxLayout:

    orientation: "vertical"
    padding_horizontal: 20

    SubjectButton:
       text: "Subject 1"

    SubjectButton:
      text: "Subject 2"

    SubjectButton:
      text: "Subject 3"

    SubjectButton:
      text: "Subject 4"

结果:

二审:

#:kivy 1.9.0

#: set sb_width 120
#: set sb_height 40
#: set sb_margin_left 20

<SubjectButton@Button>:

size_hint: None, None
height: sb_height
width: sb_width


RelativeLayout:

Label:
    text: "Choose Subject:"
    font_size: "16sp"
    bold: True
    halign: "left"
    pos: 0, root.height - 5

SubjectButton:
    text: "Subject 1"
    pos: sb_margin_left, root.height - sb_height

SubjectButton:
    text: "Subject 2"
    pos: sb_margin_left, root.height - 2 * sb_height

SubjectButton:
    text: "Subject 3"
    pos: sb_margin_left, root.height - 3 * sb_height

SubjectButton:
    text: "Subject 4"
    pos: sb_margin_left, root.height - 4 * sb_height

结果:

标签不见了!

首先让我说布局从 top-left 开始并在 bottom-left 显式定位的想法是愚蠢的(来自 PySide)。那应该如何工作?

更不用说 AnchorLayout 实际上不是布局而是对齐工具。它只影响一个 child.

我在这里错过了什么?

First trial:

您的问题是您手动设置了按钮高度并将它们设置为 Window 高度的 1/4。您看到的是它们因此溢出了 BoxLayout 高度,显然是从顶部开始的。您通常不想直接设置手动高度,而是让 BoxLayout 设置大小,以便它很好地适应 window 大小的变化。

我不确定您到底要做什么,但这里有一个使用嵌套框布局来解决明显问题的示例:

<SubjectButton@Button>:                                                                                                                            
    # size rules deleted                                                                                                                           

BoxLayout:                                                                                                                                         

    orientation: "vertical"                                                                                                                        

    Label:                                                                                                                                         
        text: "Choose Subject:"                                                                                                                    
        font_size: "16sp"                                                                                                                          
        bold: True                                                                                                                                 
        halign: "left"                                                                                                                             
        valign: 'middle'                                                                                                                           
        text_size: self.size                                                                                                                       


    BoxLayout:                                                                                                                                     
        Widget:                                                                                                                                    
            size_hint_x: None                                                                                                                      
            width: 10                                                                                                                              
        BoxLayout:                                                                                                                                 

            orientation: "vertical"                                                                                                                
            padding_horizontal: 20                                                                                                                 

            SubjectButton:                                                                                                                         
                text: "Subject 1"                                                                                                                  

            SubjectButton:                                                                                                                         
                text: "Subject 2"                                                                                                                  

            SubjectButton:                                                                                                                         
                text: "Subject 3"                                                                                                                  

            SubjectButton:                                                                                                                         
                text: "Subject 4"                                                                                                                  
        Label:                                                                                                                                     
            text: 'free space'              

请注意,我还在Label中设置了text_size: self.size,以便您的对齐生效。我还添加了垂直对齐。

我用 Widget spacer 包含了间距。可能填充参数可以做同样的事情,但我没有检查 api。

Second Trial: Label is gone!.

它并没有消失,您只是将它的 y 位置设置为屏幕顶部下方 5 个像素,这样您就看不到文字了。您可以通过添加例如查看它的真实位置以下是它的 kv 规则,这对于查看明显缺失的小部件在哪里很有用:

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

为此使用 RelativeLayout 无论如何都不是个好主意,最好像上面那样使用嵌套布局。

Let me first say that the idea that layouts start at top-left and explicit positioning at bottom-left is stupid (coming from PySide). How is that supposed to work?.

我想这在某种意义上是不一致的,但老实说,我从来没有注意到它是一个问题。它是否给您带来了特殊问题?

That's not to mention that AnchorLayout is not actually a layout but an alignment tool. It doesn't affect but a single child.

不确定你在这里的意思...AnchorLayout 像任何其他布局一样布置它的子布局。