如果你想用Python开发能在手机、电脑上同时运行的应用,却苦于没有合适的框架?试试 Kivy 吧。Kivy是一个开源的Python框架,专为跨平台应用设计,支持Windows、macOS、Linux、Android和iOS,尤其擅长处理多点触控交互。无论是简单的工具类App,还是复杂的游戏,Kivy都能胜任。
本文将从Kivy的基础概念讲起,通过实例带你掌握核心用法,最后实现一个可在手机上运行的简易计算器,让你快速入门这个强大的框架。
一、什么是Kivy?为什么选择它?
Kivy诞生于2011年,核心特点是**跨平台一致性**和**自然用户界面(NUI)** 支持。它的优势在于:
一次编写,多端运行:同样的代码可直接打包成Windows、macOS、Linux桌面应用,以及Android、iOS移动应用,无需针对不同平台修改逻辑。
原生支持多点触控:特别适合开发需要手势操作的应用(如绘图、游戏),API设计简洁,处理触摸事件比其他框架更直观。
自定义UI灵活:不依赖系统原生控件,所有UI元素均可高度自定义,确保在不同平台上的显示效果一致。
纯Python开发:无需学习Java(Android)或Swift(iOS),Python开发者可直接上手,降低跨平台开发门槛。
相比其他PythonGUI框架(如Tkinter仅支持桌面,PyQt需商业授权),Kivy的跨平台能力和触控支持是其核心竞争力,适合开发移动优先的应用。
二、环境安装:5分钟搞定
Kivy的安装需要依赖一些系统库,不同操作系统的安装步骤略有差异,但整体简单。
1. 基础安装(桌面端运行)
Windows/macOS/Linux通用步骤:
# 创建虚拟环境(可选但推荐)
python -m venv kivy_env
# 激活环境(Windows:kivy_envScriptsactivate;macOS/Linux:source kivy_env/bin/activate)
# 安装Kivy
pip install kivy
验证安装:
运行以下代码,若弹出一个带”Hello Kivy”的窗口,则安装成功:
from kivy.app import App
from kivy.uix.label import Label
class TestApp(App):
def build(self):
return Label(text="Hello Kivy!")
if __name__ == "__main__":
TestApp().run()
2. 移动端打包准备(可选)
若需要将应用打包成Android APK,需额外安装 (Kivy官方打包工具):
buildozer
# 安装buildozer
pip install buildozer
# 初始化打包配置(在项目目录执行)
buildozer init
后续可通过 生成APK(首次运行会下载Android SDK等依赖,耗时较长)。
buildozer android debug
三、核心概念:Kivy应用的组成部分
在开始写复杂应用前,先理解Kivy的几个核心概念,这是后续学习的基础。
1.
App 类:应用入口
App
所有Kivy应用都需要继承 类,并重写
App 方法——这个方法返回的控件将作为应用的根界面。
build()
2. 控件(Widget):UI的基本单元
Kivy提供了丰富的内置控件,如:
:显示文本
Label
:按钮(支持点击事件)
Button
:文本输入框
TextInput
/
BoxLayout:布局控件(用于排列子控件)
GridLayout
3. KV语言:简化UI设计
Kivy推荐用**KV语言**描述UI布局,它类似HTML+CSS,能将界面设计与逻辑代码分离,让代码更清晰。KV语言的语法简洁,例如定义一个带按钮的界面:
<MyWidget>:
Button:
text: "点击我"
on_press: print("按钮被点击了")
四、基础用法:从Hello World到交互界面
我们通过3个递进的例子,掌握Kivy的基础用法。
示例1:最简单的窗口(纯Python代码)
用纯Python代码创建一个带标签的窗口:
from kivy.app import App
from kivy.uix.label import Label
class HelloApp(App):
# build()方法返回应用的根控件
def build(self):
# 创建一个Label控件,显示文本
return Label(
text="Hello Kivy!
这是一个跨平台应用",
font_size=30, # 字体大小
color=(0.2, 0.6, 0.8, 1) # 颜色(RGBA,范围0-1)
)
if __name__ == "__main__":
# 运行应用
HelloApp().run()
运行后会显示一个窗口,文本为”Hello Kivy!”和换行内容,字体大小30,颜色为浅蓝色。
示例2:添加按钮与事件(KV语言分离UI)
用KV语言定义界面,实现按钮点击事件:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
# 用KV语言定义界面布局
kv_code = '''
<MainLayout>:
# 垂直排列控件(BoxLayout默认水平,orientation设为'vertical'垂直)
orientation: 'vertical'
padding: 50 # 内边距
spacing: 20 # 控件间距
Label:
id: info_label # 给控件起个ID,方便在Python中访问
text: "请点击按钮"
font_size: 24
Button:
text: "点击我"
font_size: 20
size_hint: 0.5, 0.1 # 宽占父控件50%,高占10%
pos_hint: {'center_x': 0.5} # 水平居中
# 绑定点击事件:调用父控件的on_button_click方法
on_press: root.on_button_click()
'''
# 加载KV语言
Builder.load_string(kv_code)
# 定义主布局类(继承BoxLayout)
class MainLayout(BoxLayout):
# 按钮点击事件的处理方法
def on_button_click(self):
# 通过ID获取Label控件,修改文本
self.ids.info_label.text = "按钮被点击了!"
# 应用类
class ButtonApp(App):
def build(self):
return MainLayout()
if __name__ == "__main__":
ButtonApp().run()
代码解析:
是布局控件,
BoxLayout 控制排列方向(水平/垂直)。
orientation
和
size_hint 用于控制控件大小和位置(相对父控件的比例)。
pos_hint
KV语言中用 表示当前布局类实例,
root 是控件ID的集合,可通过
ids 在Python中访问控件。
self.ids.xxx
示例3:文本输入与动态更新
实现一个简单的”打招呼”功能:输入姓名,点击按钮后显示问候语。
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
# KV语言定义界面(GridLayout:网格布局,2行2列)
kv_code = '''
<GreetLayout>:
cols: 2 # 2列
padding: 30
spacing: 15
Label:
text: "请输入姓名:"
font_size: 18
TextInput:
id: name_input
multiline: False # 禁止多行输入
font_size: 18
Button:
text: "打招呼"
font_size: 18
# 跨2列(row_span=1, col_span=2)
col_span: 2
size_hint: 0.3, 0.1
pos_hint: {'center_x': 0.5}
on_press: root.greet()
Label:
id: greet_label
text: ""
font_size: 20
col_span: 2 # 跨2列
'''
Builder.load_string(kv_code)
class GreetLayout(GridLayout):
def greet(self):
# 获取输入框的文本
name = self.ids.name_input.text.strip()
if name:
self.ids.greet_label.text = f"你好,{name}!"
else:
self.ids.greet_label.text = "请输入姓名~"
class GreetApp(App):
def build(self):
return GreetLayout()
if __name__ == "__main__":
GreetApp().run()
关键知识点:
按网格排列控件,
GridLayout 定义列数。
cols
用于文本输入,
TextInput 限制为单行。
multiline=False
控件通过 实现跨列(类似HTML的colspan)。
col_span
五、实战案例:开发一个跨平台计算器
我们来实现一个简易计算器,支持加减乘除运算,界面适配桌面和手机。
功能设计:
支持数字输入(0-9)和基本运算符(+、-、×、÷)。
包含清除(C)和等于(=)按钮。
界面用网格布局,在手机上可正常显示。
完整代码:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
from kivy.config import Config
# 配置窗口大小(桌面端)
Config.set('graphics', 'width', '300')
Config.set('graphics', 'height', '400')
# KV语言定义计算器界面
kv_code = '''
<Calculator>:
cols: 4 # 4列网格
spacing: 5 # 控件间距
padding: 10 # 内边距
# 显示区域(跨4列)
TextInput:
id: display
text: "0"
font_size: 30
halign: 'right' # 文本右对齐
readonly: True # 只读(禁止手动输入)
size_hint: 1, 0.2 # 高度占20%
col_span: 4
# 第一行按钮:C、±、%、÷
Button:
text: "C"
font_size: 24
background_color: 0.9, 0.9, 0.9, 1 # 浅灰色
on_press: root.clear()
Button:
text: "±"
font_size: 24
background_color: 0.9, 0.9, 0.9, 1
on_press: root.negate()
Button:
text: "%"
font_size: 24
background_color: 0.9, 0.9, 0.9, 1
on_press: root.calculate('%')
Button:
text: "÷"
font_size: 24
background_color: 1, 0.5, 0, 1 # 橙色
on_press: root.add_operator('/')
# 第二行:7、8、9、×
Button:
text: "7"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1 # 深灰色
on_press: root.add_digit('7')
Button:
text: "8"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('8')
Button:
text: "9"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('9')
Button:
text: "×"
font_size: 24
background_color: 1, 0.5, 0, 1
on_press: root.add_operator('*')
# 第三行:4、5、6、-
Button:
text: "4"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('4')
Button:
text: "5"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('5')
Button:
text: "6"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('6')
Button:
text: "-"
font_size: 24
background_color: 1, 0.5, 0, 1
on_press: root.add_operator('-')
# 第四行:1、2、3、+
Button:
text: "1"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('1')
Button:
text: "2"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('2')
Button:
text: "3"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_digit('3')
Button:
text: "+"
font_size: 24
background_color: 1, 0.5, 0, 1
on_press: root.add_operator('+')
# 第五行:0、.、=(0跨2列)
Button:
text: "0"
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
col_span: 2 # 跨2列
on_press: root.add_digit('0')
Button:
text: "."
font_size: 24
background_color: 0.2, 0.2, 0.2, 1
on_press: root.add_dot()
Button:
text: "="
font_size: 24
background_color: 1, 0.5, 0, 1
on_press: root.calculate('=')
'''
Builder.load_string(kv_code)
class Calculator(GridLayout):
def clear(self):
"""清除显示"""
self.ids.display.text = "0"
def add_digit(self, digit):
"""添加数字"""
current = self.ids.display.text
if current == "0":
# 若当前是0,直接替换
self.ids.display.text = digit
else:
# 否则追加
self.ids.display.text += digit
def add_dot(self):
"""添加小数点"""
current = self.ids.display.text
if "." not in current:
self.ids.display.text += "."
def negate(self):
"""正负号切换"""
current = self.ids.display.text
if current.startswith('-'):
self.ids.display.text = current[1:]
else:
self.ids.display.text = '-' + current
def add_operator(self, operator):
"""添加运算符"""
current = self.ids.display.text
# 若当前以运算符结尾,替换为新运算符
if current.endswith(('+', '-', '*', '/')):
self.ids.display.text = current[:-1] + operator
else:
self.ids.display.text += operator
def calculate(self, action):
"""计算结果"""
current = self.ids.display.text
if action == '%':
# 处理百分比(除以100)
try:
result = float(current) / 100
self.ids.display.text = str(result)
except:
self.ids.display.text = "错误"
elif action == '=':
# 处理等于(计算表达式)
try:
# 替换×为*,确保表达式可被eval解析
current = current.replace('×', '*').replace('÷', '/')
result = eval(current) # 简单计算(实际应用需更安全的方法)
# 若结果是整数,去除小数点
if isinstance(result, float) and result.is_integer():
result = int(result)
self.ids.display.text = str(result)
except:
self.ids.display.text = "错误"
class CalculatorApp(App):
def build(self):
return Calculator()
if __name__ == "__main__":
CalculatorApp().run()
代码解析:
布局设计:用 实现4列网格,显示区域跨4列,0按钮跨2列,确保布局紧凑。
GridLayout
样式控制:通过 区分数字键(深灰)、功能键(浅灰)和运算符(橙色),提升视觉体验。
background_color
逻辑处理:
处理数字输入,避免开头多余的0。
add_digit()
确保运算符不重复出现。
add_operator()
用
calculate() 计算表达式(实际项目中建议用更安全的计算库,如
eval)。
sympy
运行效果:
桌面端:窗口大小300×400,按钮排列整齐,点击流畅。
移动端:用 打包后,界面会自适应手机屏幕,支持触摸操作。
buildozer
六、打包成手机应用(Android为例)
要将计算器安装到手机,需用 打包:
buildozer
在项目目录执行 ,生成
buildozer init 配置文件。
buildozer.spec
编辑配置文件,设置应用名称、包名等(关键配置如下):
title = My Calculator # 应用名称
package.name = calculator # 包名
package.domain = org.test # 域名(自定义)
source.dir = . # 源码目录
version = 0.1 # 版本号
执行 ,等待打包完成(首次运行需下载Android SDK,耗时约30分钟)。
buildozer android debug
打包成功后,在 目录生成
bin,传到手机安装即可。
calculator-0.1-debug.apk
七、避坑指南:新手常见问题
中文字体显示异常Kivy默认字体不支持中文,需手动指定中文字体:
from kivy.core.text import LabelBase
# 注册中文字体(需提前准备ttf字体文件)
LabelBase.register(name='SimHei', fn_regular='SimHei.ttf')
# 在KV语言中使用:font_name: 'SimHei'
窗口大小无法修改 需在
Config.set() 导入前执行,否则不生效:
kivy.app
from kivy.config import Config
Config.set('graphics', 'width', '400')
Config.set('graphics', 'height', '500')
from kivy.app import App # 必须在Config设置后导入
打包失败确保安装了必要的系统依赖(如Ubuntu需 ),并耐心等待首次打包的依赖下载。
sudo apt install build-essential python3-dev zlib1g-dev
八、总结:Kivy适合做什么?
Kivy的优势在于跨平台和触控支持,适合开发:
简易工具类App(计算器、记事本)
教育类应用(互动课件、学习工具)
创意游戏(特别是需要多点触控的游戏)
但它也有局限:UI风格偏自定义,难以完全模仿系统原生控件(如iOS的圆润风格),复杂应用的性能可能不如原生开发。
如果你想快速用Python开发跨平台应用,Kivy绝对是值得一试的工具。掌握本文的基础和案例后,可进一步学习Kivy的高级功能(如动画、画布绘图、多页面切换),开发更复杂的应用。
最后推荐官方文档和示例库:
Kivy官方文档
Kivy示例代码


















暂无评论内容