所以,让我们说我有一个简单的pyqt应用main.py
:
import sys
from PyQt5 import QtWidgets
def main():
app = QtWidgets.QApplication(sys.argv)
w = QtWidgets.QWidget()
w.resize(250, 150)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
然后我得到了一个main.spec
,它将应用程序打包在一个文件夹中:
# -*- mode: python -*-
block_cipher = None
import inspect, os
current_path = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
a = Analysis(['main.py'],
pathex=[current_path],
binaries=[],
datas=[],
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)
exe = EXE(pyz,
a.scripts,
exclude_binaries=True,
name='main',
debug=False,
strip=False,
upx=False,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=False,
name='main')
执行pyinstaller main.spec
的结果将是一个有效的pyqt应用程序,其中包含大量文件:
所以,这就是事情,我不喜欢当前的结果,我也不喜欢使用--onefile的选项(将文件提取到临时目录的想法是不是我的一杯茶。)
现在,我发现这个有趣的article提出了解决这个问题的方法,我试图用这个简单的mcve来重现它,但出于某种原因,我已经陷入困境点。这是我所遵循的步骤:
1)我创建了一个文件pyinstaller\use_lib.py
:
import sys
import os
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), "lib"))
2)我已在上述runtime_hooks=[]
文件中将runtime_hooks=['.\\pyinstaller\\use_lib.py']
替换为main.spec
3)我重新运行了pyinstaller main.spec
,它生成了一堆凌乱的文件,如上面的截图
4)我已将所有依赖项文件手动移动到lib目录,结果如下:
问题:当我尝试运行应用程序时会崩溃:
为什么你认为它会崩溃?我搞砸了哪一步?你能解释一下如何解决它吗?
答案 0 :(得分:0)
你无法将这些dll从exe移动到另一个目录中。这些dll是静态链接的,应该放在与exe相同的目录中。
反正。查看C:\Program Files
内的一些应用程序文件夹。每个目录中都有大量文件。这就是它的方式。没有人关心,因为用户不会查看这些文件夹。
如果您要分发您的应用程序,您应该像所有其他开发人员一样。使用PyInstaller后的文件夹状态不是应用程序的最终形式,而只是初始形式:任何C / C ++应用程序都将从这种形式开始向用户开始。
因此,如果您要将应用程序分发给用户,则应使用其中一个安装程序工具。 Windows平台的最佳安装包形式是msi
数据包(针对" Windows Installer")。要构建msi
数据包,您可以使用WiX Installer
(创建msi
数据包的最简单方法)或MS Visual Studio
。此外,还有大量的安装工具可以生成exe
形式的安装包(通常它们比使用msi-tools更简单):NSIS
,Inno Setup
,{ {1}}(付费!)等。您也可以通过https://pypi.python.org/pypi数据库搜索此安装程序的名称:您可以使用一些特殊的Python数据包来管理其中一些安装工具。