从 Kivy 2.x.x 迁移至 Kivy 3.x.x¶
介绍¶
Kivy 3.x.x 相较于 Kivy 2.x.x 引入了几项变更与改进。本指南将帮助您将现有的 Kivy 2.x.x 代码库迁移至 Kivy 3.x.x。
重命名的模块和环境变量¶
从kivy.core.audio迁移至kivy.core.audio_output
在Kivy 3.x.x中,kivy.core.audio`模块已更名为`kivy.core.audio_output。
导入语句变更
要迁移你的代码,你需要更新代码库中的导入语句。例如,如果你的代码中有以下导入语句:
from kivy.core.audio import SoundLoader
你需要将其更新为:
from kivy.core.audio_output import SoundLoader
环境变量变更
环境变量也已从 KIVY_AUDIO 更名为 KIVY_AUDIO_OUTPUT。
如果你之前使用 KIVY_AUDIO 环境变量来指定音频提供者的偏好,你需要将其更新为 KIVY_AUDIO_OUTPUT。例如:
在导入Kivy之前,在Python中:
import os
# Kivy 2.x.x
os.environ['KIVY_AUDIO'] = 'sdl3,gstplayer'
import kivy
# Kivy 3.x.x
os.environ['KIVY_AUDIO_OUTPUT'] = 'sdl3,gstplayer'
import kivy
移除项¶
从 `kivy.uix.video.Video` 和 `kivy.uix.videoplayer.VideoPlayer` 中移除 `.play` 属性
在Kivy 3.x.x中,`.play`属性已从`kivy.uix.video.Video`和`kivy.uix.videoplayer.VideoPlayer`类中移除。
要迁移您的代码,您需要更新代码库中对 .play 属性的引用。例如,如果您的 Kivy 2.x.x 代码库中有以下代码:
video = Video(source='video.mp4')
# Play the video
video.play = True
# Stop the video
video.play = False
你需要将其更新为:
video = Video(source='video.mp4')
# Play the video
video.state = 'play'
# Stop the video
video.state = 'stop'
# Pause the video
video.state = 'pause'
从`kivy.uix.textinput.TextInput`中移除`padding_x`和`padding_y`属性
在 Kivy 3.x.x 中,padding_x 和 padding_y 属性已从 kivy.uix.textinput.TextInput 类中**移除**。取而代之的是,内边距现在通过统一的 padding 属性进行管理。
要更新你的代码,请将 padding_x 和 padding_y 的实例替换为 padding 属性。
padding 属性接受一个值列表,从而允许更灵活的填充配置:
[horizontal, vertical] — 例如,[10, 10]
[padding_left, padding_top, padding_right, padding_bottom] — 例如,[10, 5, 10, 5]
关于如何使用 padding 属性的更多细节,请参阅相关文档。
从`kivy.uix.filechooser.FileChooserController`中移除`file_encodings`属性
在Kivy 3.x.x中,`file_encodings`属性已从`kivy.uix.filechooser.FileChooserController`类中移除。
file_encodings 属性已被弃用,仅为向后兼容而保留,但该属性已被忽略,不再在内部使用。
要迁移您的代码,只需移除代码库中对 file_encodings 属性的所有引用即可。
移除已弃用的 `on_dropfile` 窗口事件名称
在Kivy 3.x.x中,先前已弃用的`on_dropfile`事件名称已被移除。请改用`on_drop_file`。
该事件在Kivy 2.1.0中已重命名,因此任何仍绑定到`on_dropfile`的兼容性代码现在都需要更新。
# Kivy 2.x.x (legacy/deprecated name)
from kivy.core.window import Window
def handle_drop(window, filename):
print(filename)
Window.bind(on_dropfile=handle_drop)
# Kivy 3.x.x
from kivy.core.window import Window
def handle_drop(window, filename, x, y, *args):
print(filename, x, y)
Window.bind(on_drop_file=handle_drop)
如果你直接分发或覆盖该事件,还需将任何 on_dropfile 方法的实现重命名为 on_drop_file。
移除 Kv 语言模板功能
在Kivy 3.x.x中,已弃用的Kivy语言模板功能(自1.0.5版本引入,1.7.0版本弃用)已被移除。以下内容已不再存在:
[Name@Base]:Kv 语言模板语法(任何包含[...]:选择器的 kv 文件现在在加载时会引发ParserException)。Builder.template(name, **ctx)方法和Builder.templates字典。Factory.is_template()以及Factory.register()的is_template=关键字参数。
迁移到*动态类*(<Name@Base>:)。自Kivy 1.7.0起,动态类在很大程度上取代了模板,并支持常规的Kivy属性、绑定和继承。
在 `.kv` 文件中迁移模板
# Kivy 2.x.x
[IconItem@BoxLayout]:
Image:
source: ctx.image
Label:
text: ctx.title
# Kivy 3.x.x
<IconItem@BoxLayout>:
image: ''
title: ''
Image:
source: root.image
Label:
text: root.title
注意这两处变化:[...]: 变为 <...>:,且 ctx.foo 引用变为针对规则自身声明的属性的 root.foo 引用。
迁移 `Builder.template(...)` 实例化
# Kivy 2.x.x
from kivy.lang import Builder
icon = Builder.template('IconItem', title='Hello', image='myimage.png')
# Kivy 3.x.x
from kivy.factory import Factory
icon = Factory.IconItem()
icon.title = 'Hello'
icon.image = 'myimage.png'
由于动态类属性是由规则添加到控件上的(而非在类中声明),因此在``__init__``处理其kwargs时,这些属性尚不存在——所以应在构造后通过``setattr``(或属性赋值)传递值,而不是作为构造函数kwargs。若需要构造函数kwargs支持,请将控件定义为带有显式:class:`~kivy.properties.Property`声明的常规Python类。
AccordionItem:`title_template` 和 `title_args` 已被 `title_class` 取代
: AccordionItem 控件此前使用 Kv 语言模板功能,通过 ``title_template``(字符串)和 ``title_args``(字典)属性来渲染其标题栏。这两个属性现已被移除。
替换为 title_class。它接受一个类对象或可通过工厂解析的字符串。该类使用两个关键字参数实例化:title 和 item。
要自定义标题部件的外观,可以继承 AccordionItemTitle 类(或编写任何接受 title 和 item 关键字参数的部件),并通过 title_class 传递它。
参见
title_class 文档。
时钟¶
改进的@triggered装饰器行为、实例隔离与防抖功能
在Kivy 3.x.x中,:func:`~kivy.clock.triggered`装饰器得到了显著改进。此前,当它作为方法装饰器使用时,会在类的所有实例间共享同一个触发器和状态。这意味着在一个实例上调用该方法会限制所有其他实例上的调用,且不同实例的参数可能会相互覆盖。
行为变更
改进的**实例隔离**:每个实例现在拥有自己独立的触发器和参数存储。在
widget_a上调用触发方法不再影响widget_b。改进的**惰性初始化**:现在仅在首次调用被装饰函数时才创建触发器,从而提升初始化性能。
新增 is_triggered 属性:为被装饰的函数/方法添加了一个新的
is_triggered属性,使您能够检查当前是否有待处理的调用。新增 debounce 参数:添加了一个新的 ``debounce=False``(默认值)参数。
迁移影响
这主要是一个**错误修复**和一组**新功能**。对于大多数应用程序,它不应要求代码更改。然而,如果你的代码库有意依赖不同实例之间遗留的共享节流行为,你可以通过在``@triggered``上方使用**``@classmethod``**装饰器来恢复此行为。
这确保了触发器绑定到类对象而非单个实例,从而以惯用方式恢复了共享行为。
class MyWidget(Widget):
# Default in 3.x.x: Isolated per instance
@triggered(0.1)
def sync_ui(self, *args):
pass
# Shared behavior (same as legacy 2.x.x): Shared by all instances
@classmethod
@triggered(0.1)
def sync_shared_data(cls, *args):
pass
# Optional: Debouncing (0.1s from the LAST call)
@triggered(0.1, debounce=True)
def search_input(self, text):
pass
SVG¶
移除实验性的 kivy.graphics.svg 模块
在Kivy 3.x.x中,位于``kivy.graphics.svg``的实验性``Svg``画布指令已被移除,同时移除的还有其位于``examples/svg/下的示例脚本(``benchmark.py、main.py、main-smaa.py)及其工厂注册。该模块自引入以来一直标记为实验性,现已被Kivy 3.x.x中新增的SVG支持所取代。
替换:SvgWidget / AsyncSvgWidget
对于大多数使用场景,直接使用 :class:`~kivy.uix.svg.SvgWidget`(本地资源)或 :class:`~kivy.uix.svg.AsyncSvgWidget`(网络资源)即可:
# Kivy 2.x.x
from kivy.graphics.svg import Svg
with widget.canvas:
Svg('image.svg')
# Kivy 3.x.x
from kivy.uix.svg import SvgWidget
widget.add_widget(SvgWidget(source='image.svg'))
在KV语言中:
# Kivy 3.x.x
SvgWidget:
source: 'image.svg'
替换:kivy.core.svg 图像提供器
通过标准图像管线加载SVG时(例如作为 Image 的纹理),当加载 .svg 源文件时,会自动选择新的 kivy.core.svg 提供器;无需显式导入或注册 Factory。
工厂注册
指向 kivy.graphics.svg 的 Svg 工厂条目已被移除。SvgWidget 和 AsyncSvgWidget 已以其自身名称在工厂中注册,可直接在 KV 中使用。
应用存储目录¶
Linux 用户数据目录路径变更(XDG 合规性修复)
在 Kivy 3.x.x 中,Linux 上的 App.user_data_dir 路径已修正以遵循 XDG 基础目录规范。此前,它错误地使用了 ``XDG_CONFIG_HOME``(用于配置文件);现在,它正确地使用了 ``XDG_DATA_HOME``(用于应用程序数据)。
Linux 上的路径变更:
属性 |
Kivy 2.x.x |
Kivy 3.x.x |
|---|---|---|
|
|
``~/.local/share/<app_name>``(符合 XDG 规范) |
影响:
如果你的Linux应用使用``App.user_data_dir``存储用户数据,升级到Kivy 3.x.x后,数据将存储在不同的位置。这是符合XDG规范的正确位置,但现有应用可能需要迁移其数据。
迁移选项:
**手动迁移**(推荐用于生产应用)
在应用启动期间,将现有数据从旧位置迁移到新位置:
注意: Windows、macOS、iOS 和 Android 的路径保持不变。
新增 App.user_cache_dir 属性
Kivy 3.x.x 引入了一个新的 App.user_cache_dir 属性,用于存放系统可能随时删除的临时/缓存数据。
这不是**破坏性变更**——它是一个新的可选属性。现有应用无需修改即可继续正常工作。
平台路径:
Windows:
%APPDATA%\<app_name>\CachemacOS:
~/Library/Caches/<app_name>Linux:
~/.cache/<app_name>``(遵循 ``$XDG_CACHE_HOME)Android:
Context.getCacheDir()iOS:
~/Library/Caches/<app_name>
新增 KIVY_DESKTOP_PATH_ID 环境变量
Kivy 3.x.x 引入了 KIVY_DESKTOP_PATH_ID,用于在桌面平台上设置用户友好的应用程序目录名称。
这不是**破坏性变更**——它是可选的。除非你明确设置此环境变量,否则现有应用将继续保持不变地运行。
关键特性:
设置 KIVY_DESKTOP_PATH_ID 会为 .kivy 目录创建一个**应用特定**的位置,该目录包含配置和日志文件。如果不设置 KIVY_DESKTOP_PATH_ID,配置和日志将放置在单一的全局 .kivy 目录(~/.kivy)中。
这意味着多个Kivy应用程序现在可以拥有各自独立的配置和日志目录,从而避免不同应用程序之间的冲突。
当设置时:
该变量为目录提供了人类可读的应用程序标题,使用户在浏览文件系统时更容易识别您的应用目录。
示例:
import os
os.environ['KIVY_DESKTOP_PATH_ID'] = 'My Photo Editor'
from kivy.app import App
# On Windows, creates: %APPDATA%\My_Photo_Editor\.kivy
# Instead of: %APPDATA%\photoeditor\.kivy
优先级:
KIVY_DESKTOP_PATH_ID 具有最高优先级,并影响:
KIVY_HOME目录(覆盖KIVY_HOME环境变量和虚拟环境检测)App.user_data_dir目录App.user_cache_dir目录
平台行为:
使用 KIVY_DESKTOP_PATH_ID='My Photo Editor' 的桌面路径示例:
目录 |
路径 |
|---|---|
KIVY_HOME |
|
user_data_dir |
``%APPDATA%My_Photo_Editor``(Windows) |
user_cache_dir |
``%LOCALAPPDATA%My_Photo_EditorCache``(Windows) |
警告:
如果你在现有应用中设置了 KIVY_DESKTOP_PATH_ID,你的数据将移动到新位置。你可能需要迁移现有数据(参见上面的 Linux 迁移示例)。
完整文档请参阅 控制环境 和 examples/desktop_path_id/。