使用 PyInstaller 包含 PyQt4 制作的 .exe 文件运行时出现运行时错误

3
所以,我有两个.py文件,一个是由QtDesigner生成的,另一个基本上实现了GUI的功能。使用pyinstaller,我生成了一个.exe文件,以便在没有Python和相关库的系统上使用它。
命令:pyinstaller my_script.py运行正常,没有任何错误。
问题出现在我运行.exe文件时。
错误:
Qt:检测到未经测试的 Windows 版本 10.0! Traceback(最近一次调用最先): File“site-packages\PyInstaller\loader\rthooks\pyi_rth_qt4plugins.py”,第41行, ImportError:找不到名为'PySide'的模块 在处理上述异常期间,发生了另一个异常: Traceback(最近一次调用最先): File“site-packages\PyInstaller\loader\rthooks\pyi_rth_qt4plugins.py”,第43行, 文件“”,第2237行,在_find_and_load 文件“”,第2226行,在_find_and_load_unlocked 文件“”,第1191行,在_load_unlocked 文件“”,第1161行,在_load_backward_compatible File“C:\python\lib\site-packages\PyInstaller\loader\pyimod03_importers.py”,第714行,加载模块 module = loader.load_module(fullname) RuntimeError:PyQt4.QtCore 和 PyQt5.QtCore 模块都包装 QObject 类 [11364]无法执行脚本 pyi_rth_qt4plugins

所以我尝试寻找解决方案。 这些是我尝试过的解决方案:

如何强制PyQt5用于QObject类? - 简单地将PyQt导入语句放在第一行并不能解决问题。

https://github.com/tzutalin/labelImg/issues/268 - 在这里建议删除PyQt4,并且只使用PyQt5。我在系统上安装了两个版本,有些项目依赖于PyQt5,而有些则依赖于PyQt4,因此我不想删除后者。此外,必须有其他解决方案,这使我不想这样做。

https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000551170-PyQt4-and-PyQt5-collisions-in-PyCharm-2017-2-1-when-debugging-QGIS-application - 这是一个类似的错误,所以我加入了:

matplotlib.rcParams['backend'] = 'Qt4Agg' matplotlib.rcParams['backend.qt4'] = 'PyQt4'

到我的import语句中,但还是无效。

注: 我使用的是:

PyCharm 2018.1(社区版)

Build #PC-181.4203.547,构建于2018年3月26日

JRE:1.8.0_152-release-1136-b20 amd64

JVM:由JetBrains s.r.o提供的OpenJDK 64位服务器VM

Windows 10 10.0

在IDE中代码可以正常工作。

编辑:

我的导入内容为:

from PyQt4 import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTagg as Canvas

我不会添加任何与Qt相关的其他导入语句。
编辑-2:
尝试使用cx_Freeze而不是PyInstaller,这是设置文件。
import sys
from cx_Freeze import setup, Executable

base = None
if sys.platform == "win32":
    base = "Win32GUI"

additional_mods = ['numpy.core._methods', 'numpy.lib.format', 
'numpy._distributor_init']

setup( name="ASCII2fig",
       version = "0.1",
       description = "GUI",
       options = {'build_exe': {'includes': additional_mods}},
       executables = [Executable("ASCII2figALL_main_edited.py", base=base)])

在执行脚本后,我添加了additional_mods,以解决不断出现的ImportError。有没有什么方法可以找到我应该明确提及哪些库来进行hack?

此外,我还尝试使用以下方式检查在使用Qt运行我的主要脚本时实际导入了哪些:

from modulefinder import ModuleFinder

filename = "ASCII2figALL_main_edited.py"
finder = ModuleFinder()
finder.run_script(filename)
for name, mod in finder.modules.items():
    print(name)

显然,它在内部导入了PyQt5。如前所述,我没有任何提到PyQt5的import语句。

编辑-3

因此,我将代码更改为纯PyQt5,将pyinstaller更新到最新版本-3.4,现在出现了一个新问题,它找不到Qt插件。 它仍然以某种方式导入PyQt4,我不知道在哪里。


是的,正如我所提到的,我正在使用pyinstaller。我可以尝试使用cx_Freeze。但仍然困扰着我为什么这个问题还没有被解决。 - Rick M.
@MauriceMeyer 在这个文件中我没有,我只使用PyQt4。我将导入作为编辑添加了进来。 - Rick M.
1
这并不是那么容易。虽然它绝对不像PyInstaller一样简单,但是一旦你找到正确的依赖关系,它应该会变得快速而容易。你介意发一下你有的setup.py吗?我不确定你所说的手动添加库是什么意思,一些库无法正确加载(如tkinter、某些numpy库),但你可以在安装程序中“包含”它们。 - SRT HellKitty
还有另一种选择,非常新近而且不太为人所知:fbs。我只试过一次(它能正常工作)。作者曾在官方Qt博客上受到推荐,因此我认为它相当可靠。 - z33k
@z33k 哦,很酷,我会看一下的。使用pyinstaller时,不同版本的python和pyqt仍然存在奇怪的行为。 - Rick M.
显示剩余4条评论
1个回答

1

所以,我终于让它工作了。虽然不是理想的情况,我不得不更改库为PyQt5,并确保使用PyInstaller时一切都正常,但它可以工作。这就是我所做的:

  1. 安装Python版本3.5 - 这是因为在我更新到最新的PyInstaller版本(3.4)并尝试在python 3.4上运行时,出现了一个新错误,无法找到Qt插件。经过一些搜索,我发现由于我使用在Python Extension Packages for Windows上找到的.whl文件在Python版本(3.4)上安装了PyQt5,安装程序没有捆绑。此外,当我尝试使用pip在Python 3.4上安装PyQt5时,它无法安装。

  2. 使用pip在新的Python版本上安装了PyQt5和所有其他库。 注意: 这个版本的python没有安装PyQt4,所以这很可能是原因。我将在这个Python版本上安装PyQt4,并尝试使用PyInstaller制作.exe文件,看会发生什么。

因此,总结一下,PyQt5 + Pyinstaller仅适用于Python版本>= 3.5。希望对其他人有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接