You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Kivy代码转exe报Unable to get window错误求解决方案

KivyMD代码打包exe解决「Unable to get window, abort」问题

本人开发的Python KivyMD代码可正常运行,但转换为exe可执行文件时出现「Unable to get window, abort」错误。已尝试cx_freeze、重装Kivy等方案,均未解决,求可行的打包实现方法。
原代码如下:

from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.clock import Clock
from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDFloatingActionButton


class main(BoxLayout,MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = "vertical"
        self.a = MDTextField(size_hint_y=.1, hint_text="Write for translate", helper_text="Press the button for translate",helper_text_mode="on_focus", icon_right="cursor-text", size_hint_x=None, width=300,pos_hint={'center_x':0.5,'center_y':0.96})
        self.add_widget(self.a)
        self.b = MDFloatingActionButton(size_hint_y=.1, icon='translate',pos_hint={'center_x':0.5,'center_y':0.96})
        self.add_widget(self.b)
        self.b.bind(on_release=self.show_data)
        self.layout = BoxLayout(size_hint_y=.8)
        self.add_widget(self.layout)

    def show_data(self, show):
        self.list = self.a.text.split()
        for i in range(len(self.list)):
            if not self.list[i].endswith(".png"):
                self.list[i] += ".png"
        print(self.list)
        Clock.schedule_once(self.call)

    def call(self, call):
        self.numb = 0
        Clock.schedule_interval(self.do, 0.7)

    def do(self, do):
        if (self.numb < len(self.list)):
            self.layout.clear_widgets()
            self.layout.add_widget(Image(source=self.list[self.numb]))
            self.numb += 1
        else:
            self.numb = 0
            self.list = [self.a.text]
            Clock.unschedule(self.do)
            self.layout.clear_widgets()


class app(MDApp):
    def build(self):
        return main()


if __name__ == "__main__":
    app().run()

一、先修正代码中的核心错误

原代码中main类同时继承BoxLayout和MDApp是错误逻辑——MDApp是应用入口类,布局类只需单独继承BoxLayout。同时添加资源路径处理函数,适配打包后的文件读取:

from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.clock import Clock
from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDFloatingActionButton
import sys
import os

def get_resource_path(relative_path):
    # 兼容打包前后的资源路径读取
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

class main(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = "vertical"
        self.a = MDTextField(size_hint_y=.1, hint_text="Write for translate", helper_text="Press the button for translate",helper_text_mode="on_focus", icon_right="cursor-text", size_hint_x=None, width=300,pos_hint={'center_x':0.5,'center_y':0.96})
        self.add_widget(self.a)
        self.b = MDFloatingActionButton(size_hint_y=.1, icon='translate',pos_hint={'center_x':0.5,'center_y':0.96})
        self.add_widget(self.b)
        self.b.bind(on_release=self.show_data)
        self.layout = BoxLayout(size_hint_y=.8)
        self.add_widget(self.layout)

    def show_data(self, show):
        self.list = self.a.text.split()
        for i in range(len(self.list)):
            if not self.list[i].endswith(".png"):
                self.list[i] += ".png"
            # 转换为兼容打包的资源路径
            self.list[i] = get_resource_path(self.list[i])
        print(self.list)
        Clock.schedule_once(self.call)

    def call(self, call):
        self.numb = 0
        Clock.schedule_interval(self.do, 0.7)

    def do(self, do):
        if (self.numb < len(self.list)):
            self.layout.clear_widgets()
            self.layout.add_widget(Image(source=self.list[self.numb]))
            self.numb += 1
        else:
            self.numb = 0
            self.list = [self.a.text]
            Clock.unschedule(self.do)
            self.layout.clear_widgets()

class app(MDApp):
    def build(self):
        return main()

if __name__ == "__main__":
    app().run()

二、使用PyInstaller打包的具体步骤

1. 安装PyInstaller

pip install pyinstaller

2. 生成spec配置文件

在代码所在目录执行:

pyi-makespec --name translate_app main.py

生成translate_app.spec文件。

3. 修改spec文件适配KivyMD

打开translate_app.spec,修改Analysis部分,添加KivyMD资源、你的图片文件及缺失的模块:

# -*- mode: python ; coding: utf-8 -*-
import os
from kivymd import hooks_path as kivymd_hooks_path

block_cipher = None

a = Analysis(
    ['main.py'],
    pathex=[],
    binaries=[],
    # 配置需要打包的资源:当前目录下的png图片、KivyMD内置图标
    datas=[
        ('*.png', '.'),
        (os.path.join(os.path.dirname(__file__), 'venv/Lib/site-packages/kivymd/images'), 'kivymd/images')
    ],
    # 手动添加KivyMD动态导入的模块,避免打包遗漏
    hiddenimports=['kivymd.uix.button', 'kivymd.uix.textfield', 'kivy.uix.image', 'kivy.clock'],
    hookspath=[kivymd_hooks_path],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='translate_app',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,  # 若要隐藏控制台窗口,改为False
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

注意:kivymd/images的路径需根据你的虚拟环境实际位置调整

4. 执行打包

pyinstaller translate_app.spec

打包完成后,exe文件位于dist/translate_app目录下,将你的png图片放入该目录即可运行。

三、关键注意事项

  • 禁止布局类继承MDApp,否则会导致应用初始化冲突,引发窗口创建失败;
  • 必须通过sys._MEIPASS处理资源路径,打包后代码无法直接读取本地相对路径;
  • 利用KivyMD的hookspath可自动处理部分依赖,减少手动添加hiddenimports的工作量;
  • 若仍报错,尝试关闭杀毒软件——部分杀毒软件会拦截PyInstaller生成的启动程序。

内容的提问来源于stack exchange,提问作者NUrluk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 09:45:02