使用 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"
为什么你实际上同时使用tkinter
和PyQt5
?一个应该足以提供一个 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、PyQt5、Python3 构建的 exe 无法导入 ExtensionLoader_PyQt5_QtWidgets.py 并运行