Python Kivy应用打包EXE后出现RecursionError问题求助
Kivy应用打包为EXE后运行报错:AttributeError与RecursionError
错误信息
Traceback (most recent call last): File "logging\__init__.py", line 1103, in emit AttributeError: 'NoneType' object has no attribute 'write' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "logging\__init__.py", line 1103, in emit AttributeError: 'NoneType' object has no attribute 'write' ... RecursionError: maximum recursion depth exceeded
程序代码
main.py
import random import sys from kivy.app import App from kivy.uix.widget import Widget from kivy.lang import Builder from kivy.config import Config Config.set('graphics', 'resizable', '0') # Designate Our .kv design file Builder.load_file('main.kv') class MyLayout(Widget): def release(self): self.ids.my_button.background_color = 5 / 255, 225 / 255, 120 / 255, 1 self.ids.my_button.color = 1, 1, 1, 1 def press(self): # Create variables for our widget # Update the label deck = list(range(1, 43)) random.shuffle(deck) # Create list of 6 values, and assign each with a number between 1 and 42 random_numbers = [0, 1, 2, 3, 4, 5] for i in range(0, 6): random_numbers[i] = deck.pop() # Sort the array from lowest to highest random_numbers.sort() self.ids.my_button.background_color = 50 / 255, 225 / 255, 120 / 255, 1 self.ids.my_button.color = 180 / 255, 180 / 255, 180 / 255, 1 self.ids.name_label.text = f'{random_numbers[0]} ' \ f'{random_numbers[1]} ' \ f'{random_numbers[2]} ' \ f'{random_numbers[3]} ' \ f'{random_numbers[4]} ' \ f'{random_numbers[5]}' class AwesomeApp(App): def build(self): return MyLayout() sys.setrecursionlimit(2000) if __name__ == '__main__': AwesomeApp().run()
main.kv
<MyLayout> BoxLayout: orientation: "vertical" size: root.width, root.height Label: font_name: "files/cambriab.ttf" id: name_label text: "If you had 530M dinars, what would you do with it?" font_size: 32 Button: id: my_button size_hint: .4, .2 font_size: 32 font_name: "files/cambriaz.ttf" text: "Make me rich!" pos_hint: {'center_x': 0.5} background_color: 5/255,225/255,120/255,1 on_press: root.press() on_press: hassanGIF.anim_delay = 1/50 on_press: hassanGIF._coreimage.anim_reset(True) on_release: root.release() Image: id: hassanGIF source: 'files/sequence.zip' anim_delay : -1 anim_loop: 1 center_x: self.parent.center_x center_y: self.parent.center_y+400 size: root.width-400, root.height-400
已尝试操作
- 用多种打包工具打包,均无效
- 设置
sys.setrecursionlimit(2000),未解决递归错误
解决方案
1. 修复日志输出的NoneType问题
打包后Kivy默认日志输出流会变为None,需手动配置日志处理器:
在main.py开头添加以下代码:
import logging from logging.handlers import RotatingFileHandler # 重置日志配置,避免输出流为空 logger = logging.getLogger('kivy') logger.handlers.clear() handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=5) handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logger.addHandler(handler) logger.setLevel(logging.INFO)
2. 修复递归错误根源
递归错误并非单纯提升上限就能解决,问题出在私有API调用上:
- 移除
main.kv中on_press: hassanGIF._coreimage.anim_reset(True)这一行 - 替换为Kivy官方支持的动画重置方法,修改后的
on_press事件如下:
on_press: root.press() on_press: hassanGIF.reload() on_press: hassanGIF.anim_delay = 1/50
3. 规范PyInstaller打包配置
使用PyInstaller打包时,必须正确包含资源和依赖:
- 创建
app.spec文件:
# -*- mode: python ; coding: utf-8 -*- from kivy_deps import sdl2, glew block_cipher = None a = Analysis( ['main.py'], datas=[('files/*', 'files')], # 打包files目录下的所有资源 hiddenimports=['kivy.core.window.window_sdl2'], cipher=block_cipher, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], name='AwesomeApp', console=False, # 不需要控制台窗口可设为False,调试时设为True upx=True, )
- 执行打包命令:
pyinstaller app.spec
4. 其他注意事项
- 确保
files目录下的字体、GIF压缩包路径正确,打包时已被包含 - 移除代码中的
sys.setrecursionlimit(2000),递归错误解决后无需修改默认上限
内容的提问来源于stack exchange,提问作者Ballen Abdullah
相关产品推荐
相关产品推荐

