在Kivy的.kv文件中引用根目录以解决Nuitka编译后图片加载问题
解决Nuitka编译Kivy程序后KV文件无法加载图片的问题
问题场景
用Nuitka编译根目录下的.py、.kv及图片文件后,生成的exe无法加载背景、按钮等图片。测试发现,在Python代码里通过以下方式引用图片能正常加载:
import os _local_dir = os.path.dirname(os.path.realpath(__file__)) bg = PhotoImage(file=_local_dir + "/bg_select.png")
但多数图片是在KV布局文件中引用的,KV文件无法直接使用变量,导致编译后找不到图片路径。
有效Python代码示例(编译后可正常加载图片)
import os import tkinter as tk from tkinter import PhotoImage, Label as tkinterlabel from kivy.app import App from kivy.uix.boxlayout import BoxLayout _local_dir = os.path.dirname(os.path.realpath(__file__)) class MyLayout(BoxLayout): pass class MyApp(App): def __init__(self, **kwargs): super(MyApp, self).__init__(**kwargs) self.current_user = os.getlogin() self.selected_items = [] def securityPolicy(self): if "Configure Security Policies" in self.phase_1_features: win = tk.Tk() bg = PhotoImage(file=_local_dir + "/bg_select.png") background = tkinterlabel(win, image=bg) background.place(x=0, y=0, relwidth=1, relheight=1) win.configure(bg='#0a1d32') win.geometry("350x190") win.title('Select Security Policy') win.resizable(0, 0) win.mainloop() def build(self): return MyLayout() if __name__ == '__main__': MyApp().run()
KV文件示例(编译后无法加载图片)
<MyLayout> BoxLayout: background_color: (33/255,98/255,166/255,1) orientation: "vertical" padding: 25 size: root.width, root.height spacing: 10 canvas.before: Rectangle: pos: self.pos size: root.width, root.height source:'box_bg.png'
解决方案
方法1:添加本地目录到Kivy资源搜索路径
在Python代码最开头,把当前脚本所在目录添加到Kivy的资源搜索路径中,这样KV文件里直接写图片文件名就能自动匹配到正确路径。
修改后的Python代码开头:
import os from kivy.resources import resource_add_path # 获取当前脚本的本地目录 _local_dir = os.path.dirname(os.path.realpath(__file__)) # 将本地目录加入Kivy资源搜索路径 resource_add_path(_local_dir) # 后续的Kivy代码...
KV文件无需修改,保持原来的source:'box_bg.png'即可,不管是运行源码还是编译后的exe都能正常加载图片。
方法2:在App类中定义全局属性,KV文件直接引用
在App类里定义一个存放本地目录的属性,然后在KV文件中通过app.属性名来拼接图片路径。
Python代码修改:
import os from kivy.app import App _local_dir = os.path.dirname(os.path.realpath(__file__)) class MyApp(App): local_dir = _local_dir # 定义全局属性供KV文件调用 def __init__(self, **kwargs): super().__init__(**kwargs) # ... 你的其他代码
KV文件修改:
<MyLayout> BoxLayout: # ... 其他布局属性 canvas.before: Rectangle: pos: self.pos size: root.width, root.height source: app.local_dir + '/box_bg.png'
方法3:打包资源为Kivy资源包(适用于多资源场景)
如果项目中有大量图片资源,可以把它们打包成Kivy资源包,编译时一同打包。代码中通过resource_find方法获取图片路径:
from kivy.resources import resource_find # 获取图片路径 img_path = resource_find('box_bg.png')
不过这种方法相对复杂,前两种方法更直接解决KV文件的路径问题。
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

