Kivy 简明教程

Kivy - Grid Layouts

GridLayout 是 Kivy 中一个常用的布局类型。GridLayout 对象充当容器网格。它将窗口区域划分为指定数量的行和列,并将其他小组件放入单元格中。

GridLayout 类在 kivy.uix.gridlayout 模块中定义。该对象至少必须有一个已定义的属性 - rows 和 cols。如果您未指定这两个中的任何一个,Kivy 会引发 GridLayoutException。

from kivy.uix.gridlayout import GridLayout
grid = GridLayout(**kwargs)

properties of GridLayout 对象如下 −

  1. cols − 网格中的列数。您无法再将其设置为负值。cols 是一个 NumericProperty,默认为 None。

  2. rows − 网格中的行数。您无法再将其设置为负值。rows 是一个 NumericProperty,默认为 None。

  3. cols_minimum − 每列的最小宽度的字典。字典键是列号(例如 0、1、2……)。它是一个 DictProperty,默认为 {}。

  4. rows_minimum − 每行的最小高度的字典。字典键是行号(例如 0、1、2……)。它是一个 DictProperty,默认为 {}。

  5. minimum_width - 自动计算包含所有子项所需的最小宽度。它是一个 NumericProperty,默认为 0。它是只读的。

  6. minimum_height - 自动计算包含所有子项所需的最小高度。它是一个 NumericProperty,默认为 0。它是只读的。

  7. orientation − 布局的方向。该属性决定小组件如何按顺序放置在网格中的单元格中。“orientation”是一个 OptionProperty。它的有效值如下 −'lr-tb' − 从左至右、从上至下依次填充单元格。'tb-lr' − 从上到下、从左到右依次填充单元格。'rl-tb' − 从右到左、从上到下依次填充单元格。'tb-rl' − 从上到下、从右到左依次填充单元格。'lr-bt' − 从左到右、从下到上依次填充单元格。'bt-lr' − 从下到上、从左到右依次填充单元格。'rl-bt' − 从右到左、从下到上依次填充单元格。'bt-rl' − 从下到上、从右到左依次填充单元格。

orientation 属性的默认值为 ‘lr-tb’。

  1. row_default_height − 行使用的默认最小尺寸。row_default_height 是一个 NumericProperty,默认为 0。

  2. row_force_default − 如果为 True,则忽略子元素的 height 和 size_hint_y,并使用默认行高。row_force_default 是一个 BooleanProperty,默认为 False。

  3. spacing −: 子元素之间的间距:[spacing_horizontal, spacing_vertical]。spacing 是一个 VariableListProperty,默认为 [0, 0]。

  4. padding − 布局框与其子元素之间的内边距:[padding_left, padding_top, padding_right, padding_bottom]。padding 是一个 VariableListProperty,默认为 [0, 0, 0, 0]。

默认情况下,所有小组件具有相同尺寸。这是因为默认的 size_hint 为 (1,1)。

def build(self):
   self.lo = GridLayout(cols=2)
   self.b1 = Button(text='Button 1', font_size=20)
   self.b2 = Button(text='Button 2', font_size=20)
   self.b3 = Button(text='Button 3', font_size=20)
   self.b4 = Button(text='Button 4', font_size=20)
   self.lo.add_widget(self.b1)
   self.lo.add_widget(self.b2)
   self.lo.add_widget(self.b3)
   self.lo.add_widget(self.b4)
   return self.lo

使用此代码,您将得到以下布局 −

kivy grid layouts

现在,让我们将 Hello 按钮的 size 固定为 250px,而不是使用“size_hint_x=None”。

self.lo = GridLayout(cols = 2)

self.b1 = Button(
   text='Button 1', font_size=20,
   size_hint_x=None, width=250
)

self.b2 = Button(text='Button 2', font_size=20)

self.b3 = Button(
   text='Button 3', font_size=20,
   size_hint_x=None, width=250
)

self.b4 = Button(text='Button 4', font_size=20

App 窗口如下所示 −

kivy grid layouts2

如果我们将 row_default_height 定义为 100 并设置“row_force_default=True”−

self.lo = GridLayout(
cols=2, row_force_default=True, row_default_height=100
)
self.b1 = Button(
text='Button 1', font_size=20, size_hint_x=None, width=250
)
self.b2 = Button(text='Button 2', font_size=20)
self.b3 = Button(
text='Button 3', font_size=20, size_hint_x=None, width=250
)
self.b4 = Button(text='Button 4', font_size=20)

现在窗口外观如下 −

kivy grid layouts3

Example 1

本程序中,我们在网格布局中添加了 15 个按钮,分为四列。每个按钮的标题是 1 到 15 之间的唯一随机生成数字。为此目的使用了 random 模块中的 randint() 函数。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.config import Config
import random

Config.set('graphics', 'width', '720')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '1')

class MyApp(App):
   def build(self):
      self.grid = GridLayout(cols = 4)
      nums=[]
      for i in range(1,16):
         while True:
            num = random.randint(1,15)
            if num not in nums:
               nums.append(num)
               self.grid.add_widget(Button(text = str(num)))
               break
      return self.grid

if __name__ == '__main__':
   MyApp().run()

Output

当你运行此代码时,它将生成以下输出窗口 −

kivy grid layouts4

Example 2

Kivy 中的 GridLayout 没有按行和/或列跨越小部件的规定。也不可能按行数和列数放置小部件。

需要在一个两列网格中排列几个标签和文本输入框,但下面的提交按钮应跨两列。为实现此目的,我们在一个列网格内放置一个 2 列网格,并在其下方放置一个按钮。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window

Window.size = (720, 400)

class DemoApp(App):
   def build(self):
      self.grid = GridLayout(rows=2)
      self.top_grid = GridLayout(
         cols=2, row_force_default=True,
         row_default_height=100
      )
      self.top_grid.cols = 2
      self.top_grid.add_widget(
         Label(text="Name: ", size_hint_x=None, width=250)
      )
      self.fname = TextInput(
         multiline=False, size_hint_x=None, width=650
      )
      self.top_grid.add_widget(self.fname)
      self.top_grid.add_widget(Label(text="Address: "))
      self.address = TextInput(multiline=True)
      self.top_grid.add_widget(self.address)
      self.top_grid.add_widget(Label(text="College: "))
      self.college = TextInput(multiline=False)
      self.top_grid.add_widget(self.college)
      self.grid.add_widget(self.top_grid)
      self.b1 = Button(text='Submit', size_hint_y=None, height=200)
      self.grid.add_widget(self.b1)
      return self.grid

if __name__ == '__main__':
   DemoApp().run()

Output

当你运行此代码时,它将生成以下输出窗口 −

kivy grid layouts submit