使用 cx_Freeze 从 .py 构建一个 .exe 文件

Posted

技术标签:

【中文标题】使用 cx_Freeze 从 .py 构建一个 .exe 文件【英文标题】:Build an .exe file from .py with cx_Freeze 【发布时间】:2018-12-04 15:12:28 【问题描述】:

我正在尝试从 python (setup.py) 上的项目制作可执行文件

    import sys
    import xlrd
    import pyodbc
    import tkinter as tk
    import os.path
    from PyQt5.QtCore import pyqtSlot
    from PyQt5.QtWidgets import QApplication,QDialog
    from PyQt5.uic import loadUi
    from PyQt5 import QtGui
    from tkinter import filedialog
    from datetime import datetime, timedelta
    from win32api import GetSystemMetrics
    from cx_Freeze import setup, Executable

    base = None    

    PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
    os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
    os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')
    #os.environ['TCL_LIBRARY'] = r'C:\Users\PQ946KK\AppData\Local\Programs\Python\Python37\tcl\tcl8.6'
    #os.environ['TK_LIBRARY'] = r'C:\Users\PQ946KK\AppData\Local\Programs\Python\Python37\tcl\tk8.6'

    executables = [Executable("Load File.py",
                   base=base,
                   icon="BI Icon.ico")] 

    packages = ["tkinter","pyodbc","PyQt5","datetime","win32api"]

    files = ["BI Icon.ico","Load Excel.ui",
             r"C:\Users\PQ946KK\Documents\Leti\Proyectos\PowerBI\Icon\arrow up load.png",
             os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
             os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll')]

    options = 
        'build_exe':     
            'packages':packages,
            'include_files':files,
        ,    
    

    setup(
        name = "LoadFile BI",
        options = options,
        version = "0.1",
        description = 'Ejecutable de Aplicacion Load File',
        executables = executables
    )

每当我构建时,它只会创建几个文件(只要我记得它应该创建更多文件和文件夹)

    (base) C:\Users\XXXXXX\Documents\Leti\Proyectos\PowerBI>python setup.py build
    running build
    running build_exe
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\lib\site-packages\cx_Freeze\bases\Console.exe -> build\exe.win-amd64-3.6\Load File.exe
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-stdio-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-stdio-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\python36.dll -> build\exe.win-amd64-3.6\python36.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\VCRUNTIME140.dll -> build\exe.win-amd64-3.6\VCRUNTIME140.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-math-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-math-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-locale-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-locale-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-string-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-string-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-runtime-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-runtime-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-convert-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-convert-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-time-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-time-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-environment-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-environment-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-process-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-process-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-heap-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-heap-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-conio-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-conio-l1-1-0.dll
    copying C:\Users\PQ946KK\AppData\Local\Continuum\anaconda3\api-ms-win-crt-filesystem-l1-1-0.dll -> build\exe.win-amd64-3.6\api-ms-win-crt-filesystem-l1-1-0.dll

    (base) C:\Users\XXXXXX\Documents\Leti\Proyectos\PowerBI>python setup.py build

我已经尝试重新安装 Python、Anaconda 并设置全局变量,但仍然没有得到相同的结果,当然 .exe 文件也不起作用。错误信息:

致命的 Python 错误:Py_Initialize: 无法加载文件系统编解码器 ModuleNotFoundError:没有名为“编码”的模块

我还要提一下,这是我第一次使用单独的 .ui 文件构建文件。

【问题讨论】:

【参考方案1】:

    您是否尝试将encodings 添加到packages 列表选项?

    packages = ["tkinter","pyodbc","PyQt5","datetime","win32api","encodings"]
    

    还请注意,如果您使用 cx_Freeze 版本 5.1.1(当前默认版本)或 5.1.0 冻结您的应用程序,您需要将 TCL 和 TK DLL 包含到子目录 lib 中。您可以通过将元组 (source, destination) 传递给 include_files 列表选项的相应条目来做到这一点:

    files = ["BI Icon.ico", "Load Excel.ui",
             r"C:\Users\PQ946KK\Documents\Leti\Proyectos\PowerBI\Icon\arrow up load.png",
             (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
             (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))]
    

    如果您构建一个 GUI 应用程序(看起来),您还应该在安装脚本中修改 base 的定义,如下所示,然后在 Executable 中使用它:

    # GUI applications require a different base on Windows (the default is for a console application).
    base = None
    if sys.platform == "win32":
        base = "Win32GUI"
    

    为什么你实际上同时使用tkinterPyQt5?一个应该足以提供一个 GUI,不是吗?如果您不在应用程序中使用tkinter(我猜),您通常需要通过excludes 列表选项在安装脚本中明确排除它(当然,从packages 列表中删除它和删除import tkinter as tk):

    packages = ["pyodbc","PyQt5","datetime","win32api"]
    
    files = ...
    
    excludes = ['tkinter']
    
    options = 
        'build_exe':     
            'packages':packages,
            'include_files':files,
            'excludes':excludes
            ,    
        
    

    您可能不再需要提供 TK 和 TCL DLL。

    使用单独的.ui 文件对cx_Freeze 没有问题。您只应确保冻结的应用程序在正确的位置查找 .ui 文件。

【讨论】:

嘿!感谢您的回答,我已经设法意识到有3个问题。首先,有些文件似乎已损坏,所以我重新安装所有文件。然后,PyQt5 的版本不兼容,所以我安装了一个

以上是关于使用 cx_Freeze 从 .py 构建一个 .exe 文件的主要内容,如果未能解决你的问题,请参考以下文章

cx_freeze 无法构建 numpy 可执行文件

.py 到 .exe 使用 cx_freeze 导致错误

使用 cx_freez 构建 exe 时出错

使用 cx_Freeze、PyQt5、Python3 构建的 exe 无法导入 ExtensionLoader_PyQt5_QtWidgets.py 并运行

Python cx_freeze 构建错误

使用 cx_freeze 将 3 个 .py 文件组合成一个独立的应用程序?