Python 3.x PyInstaller&引用;无法找到或加载Qt平台插件";“窗口”;
我的PyInstaller规范:Python 3.x PyInstaller&引用;无法找到或加载Qt平台插件";“窗口”;,python-3.x,qt,pyqt5,pyinstaller,static-linking,Python 3.x,Qt,Pyqt5,Pyinstaller,Static Linking,我的PyInstaller规范: # -*- mode: python -*- block_cipher = None a = Analysis(['test.py'], pathex=['C:\\Users\\admin\\compile'], binaries=[('C:\\Python361\\Lib\\site-packages\\PyQt5\\Qt\\plugins\\platforms\\qwindows.dll', 'qwi
# -*- mode: python -*-
block_cipher = None
a = Analysis(['test.py'],
pathex=['C:\\Users\\admin\\compile'],
binaries=[('C:\\Python361\\Lib\\site-packages\\PyQt5\\Qt\\plugins\\platforms\\qwindows.dll', 'qwindows.dll')],
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,
a.binaries,
a.zipfiles,
a.datas,
name='test',
debug=False,
strip=False,
upx=False,
runtime_tmpdir=None,
console=False , icon='icon.ico')
因此,我遇到了一个问题,我将使用pip最新版本的PyInstaller编译我的PyQt5 5.8.2(使用Python 3.6.1)程序,它可以工作!静态链接的onefile可执行文件在我的计算机上运行,上面有所有的Qt内容
但是,我在任何尚未设置Qt环境的计算机或虚拟机上测试它,它在启动时崩溃,因为“找不到或加载Qt平台插件“windows”错误。如果您查看规范,您会注意到我试图手动将DLL存储在二进制列表中,以便PyInstaller将其存储在可执行文件中,但这不起作用
我想知道我需要更改什么,这样我就可以编译我的应用程序,而不必做一些事情,比如将platforms文件夹包含在带有可执行文件的文件夹中(我希望所有内容都包含在可执行文件中),这会像我没有意识到的spec文件中的更改那样简单,以便它将DLL存储在可执行文件中吗
顺便说一下,这不是复制品。我看了其他一些问题,所有这些问题要么是针对不同类型的应用程序,要么是解决方案是降级或将DLL存储在文件夹中,而我无法做到这两个
编辑:所以我把它改为onedir只是想看看它是否在那里,而qwindows.dll就在文件夹里面。还有一个qt5_插件文件夹,其中包含一个平台文件夹,该文件夹还包含一个qwindows.dll。那么,它是如何不检测dll的呢?我只是将我的pyqt5包更新为5.10.1并修复了它。似乎有两种解决方案,第一种对我来说很好:
- 将平台目录复制到可执行文件的目录。您可以在类似于
c:\Users\\envs\\Library\plugins\platforms的位置找到平台目录
- 升级到pyqt的更新版本:
conda安装-c anaconda pyqt
我遇到了一个问题,我的python代码运行良好,但编译的.exe文件将提供“无法找到或加载Qt平台插件窗口”问题。我通过将程序目录中的
~PyQt5\Qt\plugins\platforms
文件夹(使用pyinstaller--onedir main.py
生成)复制到保存.exe文件的文件夹中,解决了这个问题
在我的例子中,“帮助”我的程序检测所需.dll的唯一方法似乎是在
main.exe
旁边有platforms
文件夹。在使用pyinstaller--onefile main.py
之后,将platforms
文件夹粘贴到程序目录也可以使程序正常工作。这是一个老问题,但我已经寻找解决此问题的方法好几天了,最后我成功地解决了它,而不必手动复制文件夹。
因为这个问题也使用了.spec
文件,所以我认为这是正确的位置。
这个想法是.exe
在路径/platforms/*.dll
中查找.dll
s,因此我只是将所有dll添加到spec文件中的二进制数组中,它们在包中的路径是platforms/*.dll
。这是因为binaries
是一个元组数组,其中第一个值是文件的路径,第二个值是捆绑包中的路径(几乎就是.exe“容器”中的路径)
除此之外,顶部的状态是mode:python
,我假设这意味着它是作为python脚本执行的,因此它应该支持变量、字符串和连接。所以我的规范文件最终看起来像这样:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
pf_foldr='C:\\Users\\Gabryxx7\\anaconda3\\envs\\<env_name>\\Library\\plugins\\platforms\\'
a = Analysis(['C:\\Users\\Gabryxx7\\PycharmProjects\\<proj_name>\\program.py'],
pathex=['C:\\Users\\Gabryxx7\\PycharmProjects\\<proj_name>\\'],
binaries=[(pf_foldr+'qwindows.dll', 'platforms\\qwindows.dll'),
(pf_foldr+'qdirect2d.dll', 'platforms\\qdirect.dll'),
(pf_foldr+'qoffscreen.dll', 'platforms\\qoffscreen.dll'),
(pf_foldr+'qwebgl.dll', 'platforms\\qwebgl.dll')
],
datas=[],
hiddenimports=['GUI', 'API', 'Threading', 'ssl', 'pyodbc'],
hookspath=[],
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='programName',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True ) # False to avoid the console
#-*-模式:python;编码:utf-8-*-
分组密码=无
pf\u foldr='C:\\Users\\Gabryxx7\\anaconda3\\envs\\\\Library\\plugins\\platforms\'
a=分析(['C:\\Users\\Gabryxx7\\pycharm项目\\\\program.py'],
pathex=['C:\\Users\\Gabryxx7\\Pycharm项目\\\\'],
二进制文件=[(pf_foldr+'qwindows.dll','platforms\\qwindows.dll'),
(pf_foldr+'qdirect2d.dll','platforms\\qdirect.dll'),
(pf_foldr+'qoffscreen.dll','platforms\\qoffscreen.dll'),
(pf_foldr+'qwebgl.dll','platforms\\qwebgl.dll')
],
数据=[],
hiddenimports=['GUI'、'API'、'Threading'、'ssl'、'pyodbc'],
hookspath=[],
运行时挂钩=[],
不包括=[],
win\u no\u Preference\u redirects=False,
win_private_assemblies=False,
密码=分组密码,
无存档=假)
pyz=pyz(a.pure,a.zipped_数据,
密码=分组密码)
exe=exe(pyz,
a、 剧本,
a、 二进制文件,
a、 拉链,
a、 数据,
[],
name='programName',
debug=False,
引导加载程序\u忽略\u信号=False,
strip=False,
upx=真,
upx_exclude=[],
运行时\u tmpdir=None,
控制台=真)#假以避免控制台
我以前尝试过我在网上找到的所有解决方案:设置环境变量
QT\u QPA\u平台\u插件\u路径
,重新安装Anaconda,更新所有软件包,尝试使用PyPi版本,但没有venvs,但没有任何效果。最后,用dll
复制platforms
文件夹成功了,规范文件编辑也成功了,从而避免了手动操作。在我的大脑几乎爆炸后,我试图解决这个问题,我找到了一个适合我的解决方案
在SPEC文件中,我添加了一个子句:upx\u exclude=['qwindows.dll',
结果表明,在PyInstaller冻结过程中压缩时,此DLL已损坏。将DLL添加到upx\u exclude
子句可防止此pro
...
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='Hydro Tax Automation App',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=['qwindows.dll'],
runtime_tmpdir=None,
console=False)
import os
import sys
from pathlib import Path
os.environ['QT_PLUGIN_PATH'] = str( Path( sys._MEIPASS ) / 'PyQt6/Qt6' )
from pathlib import Path
root = Path.cwd()
qtRoot = root / 'env/Lib/site-packages/PyQt6/Qt6'
analysis = Analysis(
scripts = [
root / 'src/main.py',
],
pathex = [
root,
qtRoot / 'bin',
],
binaries = [
( qtRoot / 'plugins/platforms/qwindows.dll', 'PyQt6/Qt6/plugins/platforms' ),
( qtRoot / 'plugins/styles/qwindowsvistastyle.dll', 'PyQt6/Qt6/plugins/styles' ),
],
hiddenimports =[
'PyQt6.sip',
],
runtime_hooks = [
'pyQtHook.py',
],
)
pyz = PYZ( analysis.pure, analysis.zipped_data )
exe = EXE(
pyz,
analysis.scripts,
analysis.binaries,
analysis.zipfiles,
analysis.datas,
name = 'MyApp',
console = False,
upx = True,
upx_exclude = [
'qwindows.dll',
'qwindowsvistastyle.dll',
],
)