在kivy论坛中没有得到答复,因此请在这里尝试.
Didn't get a response in the kivy forum, so trying here.
当我将教程pong代码编译为一个文件可执行文件时,我仍然必须将pong.kv文件包含在同一文件夹中才能运行. 否则,启动exe时会出现以下错误:
When I compile the tutorial pong code as a one file executable, I must still include the pong.kv file in the same folder for it to run. Otherwise, I get the following error when launching the exe:
GL: EXT_framebuffer_object is supported [INFO ] [GL ] OpenGL version [INFO ] [GL ] OpenGL vendor [INFO ] [GL ] OpenGL renderer [INFO ] [GL ] OpenGL parsed version: 2, 1 [INFO ] [GL ] Shading version [INFO ] [GL ] Texture max size [INFO ] [GL ] Texture max units [INFO ] [Window ] auto add sdl2 input provider [INFO ] [Window ] virtual keyboard not allowed, single mode, not docked Traceback (most recent call last): File "", line 81, in File "c:\python34\lib\site-packages\kivy\app.py", line 802, in run root = self.build() File "", line 75, in build File "", line 20, in serveBall AttributeError: 'NoneType' object has no attribute 'center' main returned -1如何使它作为一个可执行文件运行.这是我的pong.spec文件:
How can I get it to run as one executable. Here's my pong.spec file:
# -*- mode: python -*- from kivy.deps import sdl2, glew block_cipher = None a = Analysis(['Code\main.py'], pathex=['E:\\Development\\Pong'], binaries=None, datas=None, hiddenimports=[], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) a.datas += [('Code\pong.kv', 'E:\\Development\\Pong\Code\pong.kv', 'DATA')] exe = EXE(pyz,Tree('Code'), a.scripts, a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], name='pong', debug=False, strip=False, upx=True, console=True , icon='pong.ico')请注意,我尝试将pong.kv包含在数据列表中,但这无济于事.
Note that I tried to include the pong.kv in the datas list but that didn't help.
谢谢, -拉伊
推荐答案基于KeyWeeUsr(使用PyInstaller和使用PyInstaller从Python脚本制作EXE ),并将其与Kivy的资源路径方法结合使用,这是一个可行的解决方案.我觉得这有点麻烦,因为它使用SYS._MEIPASS(我希望使用公共API),并且需要在您的Python代码中添加代码段.但是,该解决方案可以在Windows和Mac上运行,因此可以共享.
Based on the links provided by KeyWeeUsr (Bundling data files with PyInstaller and Using PyInstaller to make EXEs from Python scripts) and combining that with Kivy's resource path method, here's a workable solution. I feel it's a bit rough around the edges because it uses SYS._MEIPASS (I would prefer a public API) and requires adding a code snippet to your Python code. However, the solution works on both Windows and Mac so will share.
假设我具有以下代码层次结构:
Assume I have the following code hierarchy:
MyCode/ MyApp.py (This is the main program) myapp.kv (This is the associated kv file) MyData/ (This is where data is located that the app uses) myapp.icns (e.g. icon file for mac) myapp.ico (e.g. icon file for windows) Build/ mac/ myapp.spec (spec file to build on mac platform) pc/ myapp.spec (spec file to build on windows platform) MyHiddenImports/ (Folder containing python files for hidden imports)我在示例中添加了MyHiddenImports文件夹,以防您的代码在运行时还将另一个包含python代码的文件夹附加到sys.path中.
I added a MyHiddenImports folder to the example in case your code also appends another folder containing python code to sys.path during run time.
在MyApp.py中添加以下内容:
In MyApp.py add the following:
def resourcePath(): '''Returns path containing content - either locally or in pyinstaller tmp file''' if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS) return os.path.join(os.path.abspath(".")) if __name__ == '__main__': kivy.resources.resource_add_path(resourcePath()) # add this line my_app = MyApp()resources_add_path()告诉Kivy在哪里寻找data/.kv文件.例如,在Mac上,运行pyinstaller应用程序时,它指向/private/var/folders/80/y766cxq10fb_794019j7qgnh0000gn/T/_MEI25602,在Windows中,它指向c:\ users \ raj \ AppData \ Local \ Temp_MEI64zTut(这些文件夹在退出应用程序后会被删除,并在再次启动时创建另一个名称).
The resources_add_path() tells Kivy where to look for the data/.kv files. For example, on the Mac, when running the pyinstaller app, it pointed to /private/var/folders/80/y766cxq10fb_794019j7qgnh0000gn/T/_MEI25602 and in windows, it pointed to c:\users\raj\AppData\Local\Temp_MEI64zTut (these folders get deleted after exiting app and creates another name when launched again).
我使用以下命令创建了初始Mac模板规范文件:
I created the initial Mac template spec file with the following command:
pyinstaller --onefile -y --clean --windowed --name myapp --icon = ../../Code/Data/myapp.icns --exclude-module _tkinter --exclude-module Tkinter-排除模块附魔-排除模块扭曲../../Code/MyApp.py
pyinstaller --onefile -y --clean --windowed --name myapp --icon=../../Code/Data/myapp.icns --exclude-module _tkinter --exclude-module Tkinter --exclude-module enchant --exclude-module twisted ../../Code/MyApp.py
这是修改后的Mac OS Spec文件:
Here's the modified Mac OS Spec file:
# -*- mode: python -*- block_cipher = None a = Analysis(['../../Code/MyApp.py'], pathex=['/Users/raj/Development/Build/mac', '../../MyHiddenImports'], binaries=None, datas=None, hiddenimports=['MyHiddenImports'], hookspath=[], runtime_hooks=[], excludes=['_tkinter', 'Tkinter', 'enchant', 'twisted'], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) a.datas += [('myapp.kv', '../../MyCode/my.kv', 'DATA')] exe = EXE(pyz, Tree('../../Code/Data', 'Data'), a.scripts, a.binaries, a.zipfiles, a.datas, name='myapp', debug=False, strip=False, upx=True, console=False , icon='../../Code/Data/myapp.icns') app = BUNDLE(exe, name='myapp.app', icon='../../Code/Data/myapp.icns', bundle_identifier=None)注意事项:我将隐藏的导入路径添加到pathex,并在hiddenimports中引用了该包.我将myapp.kv文件附加到a.datas,以便将其复制到应用程序中.在EXE中,我添加了数据树.我包括了prefix参数,因为我希望将Data文件夹复制到应用程序中(而不是让孩子坐在根目录下).
Things to note: I added the hidden imports path to pathex, and referenced the package in hiddenimports. I appended the myapp.kv file to a.datas so it will be copied into the app. In the EXE, I added the Data tree. I included the prefix argument, as I wanted the Data folder to be copied into the app (versus having the children sit at the root level).
要编译代码以创建应用程序并将其放入dmg文件中,我有一个make-myapp脚本,该脚本执行以下操作:
To compile the code to create the app and put it into a dmg file I have a make-myapp script that does the following:
pyinstaller -y --clean --windowed myapp.spec pushd dist hdiutil create ./myapp.dmg -srcfolder myapp.app -ov popd cp ./dist/myapp.dmg .类似地,这是Windows规范文件:
Similarly, here's the windows spec file:
# -*- mode: python -*- from kivy.deps import sdl2, glew block_cipher = None a = Analysis(['..\\..\\Code\\Cobbler.py'], pathex=['E:\\Development\\MyApp\\Build\\pc', '..\\..\\MyHiddenImports'], binaries=None, datas=None, hiddenimports=['MyHiddenImports'], hookspath=[], runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) a.datas += [('myapp.kv', '../../Code/myapp.kv', 'DATA')] exe = EXE(pyz, Tree('..\\..\\Code\\Data','Data'), a.scripts, a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], name='myapp', debug=False, strip=False, upx=True, console=False, icon='..\\..\\Code\\Data\\myapp.ico' )并编译Windows应用程序:
And to compile the windows app:
python -m PyInstaller myapp.spec
python -m PyInstaller myapp.spec
更多推荐
Kivy:编译为单个可执行文件
发布评论