Kivy - 如何调整嵌入式锚布局的大小?
Kivy - How to Size Embedded Anchor Layouts?
我想在 .kv 文件中构建以下简单设计。
它由三部分组成:
- 一个左上角的锚点布局,由 3 列的网格布局组成。我希望它的宽度等于 window 的 20%,高度等于 window 的 75%。
- 一个右上角的Anchor Layout,由一个垂直方向的Box Layout组成。我希望它的宽度等于 window 的 80%,高度等于 window 的 75%。
- 一个左下角的Anchor Layout,暂时是空的。我希望它的高度是 window 高度的 25%。
这三个部分本身包含在一个 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"
问题 - 以设计为中心
设计位于中心。
根本原因
根是 AnchorLayout,anchor_x
和 anchor_y
的值为 'center'
。因此,它的所有子节点(AnchorLayout
s)都相对于根节点放置。
下面是您的设计视图,使用不同的颜色进行可视化。
AnchorLayout
AnchorLayout 将其子项与边框(上、下、左、右)或中心对齐。
解决方案
您的设计有三种可能的解决方案。首选方法1.
方法 1 - 否 AnchorLayout
s
此方法将所有 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 - 否 AnchorLayout
s
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 - 否 AnchorLayout
s
方法 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
我想在 .kv 文件中构建以下简单设计。
它由三部分组成:
- 一个左上角的锚点布局,由 3 列的网格布局组成。我希望它的宽度等于 window 的 20%,高度等于 window 的 75%。
- 一个右上角的Anchor Layout,由一个垂直方向的Box Layout组成。我希望它的宽度等于 window 的 80%,高度等于 window 的 75%。
- 一个左下角的Anchor Layout,暂时是空的。我希望它的高度是 window 高度的 25%。
这三个部分本身包含在一个 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"
问题 - 以设计为中心
设计位于中心。
根本原因
根是 AnchorLayout,anchor_x
和 anchor_y
的值为 'center'
。因此,它的所有子节点(AnchorLayout
s)都相对于根节点放置。
下面是您的设计视图,使用不同的颜色进行可视化。
AnchorLayout
AnchorLayout 将其子项与边框(上、下、左、右)或中心对齐。
解决方案
您的设计有三种可能的解决方案。首选方法1.
方法 1 - 否 AnchorLayout
s
此方法将所有 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 - 否 AnchorLayout
s
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 - 否 AnchorLayout
s
方法 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"
"""))