Kivy 基础

Kivy 环境的安装

Kivy 依赖许多库,如 SDL3、gstreamer、PIL、Cairo 等。它们并非全部必需,但根据您所使用的平台,安装它们可能会有些麻烦。为了简化您的开发流程,我们为 Windows、macOS 和 Linux 提供了预打包的二进制文件。

请查看以下页面之一,获取详细的安装说明:

或者,开发版本的说明可以在这里找到:

创建一个应用程序

创建一个kivy应用程序就像这样简单:

  • App 类进行子类化

  • 实现其 build() 方法,使其返回一个 Widget 实例(即你的控件树的根节点)。

  • 实例化该类,并调用其 run() 方法。

以下是一个最小化应用的示例:

import kivy
kivy.require('2.1.0') # replace with your current kivy version !

from kivy.app import App
from kivy.uix.label import Label


class MyApp(App):

    def build(self):
        return Label(text='Hello world')


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

你可以将其保存为文本文件,例如`main.py`,然后运行它。

Kivy 应用生命周期

首先,让我们熟悉一下Kivy应用的生命周期。

../_images/Kivy_App_Life_Cycle.png

如上所示,无论从哪个角度看,我们应用的入口点都是 run() 方法,在我们的例子中就是 "MyApp().run()"。我们稍后会回到这一点,但让我们从这一行开始:

from kivy.app import App

你的App的基类必须继承自`App`类。该类位于kivy安装目录下的kivy/app.py中。

备注

如果你想更深入地了解Kivy App类的功能,不妨打开那个文件看看。我们鼓励你打开代码并通读一遍。Kivy基于Python,并使用Sphinx进行文档编写,因此每个类的文档都直接包含在实际文件中。

同样地,在第5行:

from kivy.uix.label import Label

这里需要注意的一个重要事项是包/类的布局方式。uix 模块是存放用户界面元素(如布局和控件)的部分。

继续看第8行:

class MyApp(App):

这是我们`定义`Kivy应用基类的地方。在这一行中,您通常只需更改应用名称`MyApp`即可。

继续到第10行:

def build(self):

如上图所示,展示了 Kivy App Life Cycle,这是您应该初始化并返回 Root Widget 的函数。这正是我们在第 11 行所做的:

return Label(text='Hello world')

这里我们初始化一个文本为“Hello World”的Label,并返回其实例。这个Label将成为该App的根Widget。

备注

Python 使用缩进来表示代码块,因此请注意,在上述提供的代码中,第11行处类和函数的定义结束。

现在来看第14行和第15行,这部分将让我们的应用运行起来:

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

在这里,类 MyApp 被初始化,并调用了其 run() 方法。这初始化并启动了我们的 Kivy 应用程序。

运行应用程序

要运行该应用程序,请按照您操作系统的说明进行操作:

对于Windows、Linux、macOS或树莓派(RPi)。在您安装Kivy的:ref:`终端<command-line>`中,直接运行:

python main.py

对于Android或iOS平台,您的应用程序需要一些补充文件才能运行。请参阅:doc:/guide/packaging-android`或:doc:/guide/packaging-ios`以获取更多参考信息。

窗口应打开,显示一个覆盖整个窗口区域的单一标签(文本为“Hello World”)。仅此而已。

../_images/quickstart.png

自定义应用程序

让我们稍微扩展一下这个应用程序,比如做一个简单的用户名/密码页面。

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput


class LoginScreen(GridLayout):

    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.cols = 2
        self.add_widget(Label(text='User Name'))
        self.username = TextInput(multiline=False)
        self.add_widget(self.username)
        self.add_widget(Label(text='password'))
        self.password = TextInput(password=True, multiline=False)
        self.add_widget(self.password)


class MyApp(App):

    def build(self):
        return LoginScreen()


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

在第二行,我们导入了一个 Gridlayout:

from kivy.uix.gridlayout import GridLayout

该类用作我们第7行定义的根组件(LoginScreen)的基类:

class LoginScreen(GridLayout):

在类 LoginScreen 的第 9 行,我们重写了方法 __init__(),以便添加控件并定义它们的行为:

def __init__(self, **kwargs):
    super(LoginScreen, self).__init__(**kwargs)

不要忘记调用super,以实现被重载的原始类的功能。同时注意,在调用super时不要省略`**kwargs`,因为它们在内部有时会被使用,这是良好的实践。

继续看第11行及之后的内容:

self.cols = 2
self.add_widget(Label(text='User Name'))
self.username = TextInput(multiline=False)
self.add_widget(self.username)
self.add_widget(Label(text='password'))
self.password = TextInput(password=True, multiline=False)
self.add_widget(self.password)

我们要求GridLayout将其子控件管理为两列,并为用户名和密码添加一个:class:~kivy.uix.label.Label`和一个:class:`~kivy.uix.textinput.TextInput

运行上述代码后,您将看到一个窗口,其外观应如下所示:

../_images/guide_customize_step1.png

尝试调整窗口大小,您会看到屏幕上的控件会根据窗口大小自动调整自身,无需您进行任何操作。这是因为控件默认使用尺寸提示(size hinting)机制。

上面的代码没有处理用户的输入,也没有进行任何验证或其他操作。我们将在接下来的章节中更深入地探讨这一点,以及 Widget 的大小和定位。