使用 PyInstaller 后 FigureCanvas 未解释为 QtWidget

Posted

技术标签:

【中文标题】使用 PyInstaller 后 FigureCanvas 未解释为 QtWidget【英文标题】:FigureCanvas not interpreted as QtWidget after using PyInstaller 【发布时间】:2019-05-17 08:10:47 【问题描述】:

我有一个来自 matplotlib 的这个例子的轻微修改版本:https://matplotlib.org/gallery/user_interfaces/embedding_in_qt_sgskip.html

唯一改变的是导入,因为我使用的是 PySide2,所以导入看起来像这样:

from PySide2 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure

在 pycharm 中运行代码或自行运行脚本时,这可以正常工作,但是在使用 PyInstaller 创建 .exe 后,我收到以下错误:

TypeError: 'PySide2.QtWidgets.QBoxLayout.addWidget' called with wrong argument types:                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(FigureCanvasQTAgg)                                                            
Supported signatures:                                                                                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(PySide2.QtWidgets.QWidget, int=0, 
  PySide2.QtCore.Qt.Alignment=Default(Qt.Alignment))                                                                                                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(PySide2.QtWidgets.QWidget)

FigureCanvasQtAgg 似乎不再被识别为 QWidget,因此无法添加到布局中。

我已经尝试添加这些行来建议 pyside 建议 here:

os.environ["QT_API"] = "PySide2"
matplotlib.use('Qt5Agg')
matplotlib.rcParams['backend.qt5']='PySide2'

但是,这不会更改 exe 的错误消息。在 pycharm 中它仍然运行良好。

编辑:这似乎是 PySide2+PyInstaller 的一些问题,替换此行后:

from PySide2 import QtCore, QtWidgets

用这一行:

from PyQt5 import QtCore, QtWidgets

即使在使用 PyInstaller 后也能正常工作。

但我想使用 PySide2 而不是 PyQt5,有人知道解决这个问题的方法吗?

【问题讨论】:

你找到解决办法了吗? 【参考方案1】:

对于 PySide2,我在使用 PySide 5.13 版本时遇到了类似的问题。

但是,对于 PySide 5.6 版,它很好工作。

有趣的是,这个问题看起来像 matplotlib 包装器。 FigureCanvasQTAgg 的包装似乎发生了变化。一个正在工作的包装器是:Shiboken.ObjectType。虽然那个不起作用,但包装器是:sip.wrappertype

【讨论】:

【参考方案2】:

这个帖子有点老了,但是,因为它是我在谷歌上搜索问题时的第一个热门话题,而且这个解决方案还没有提到,我想我分享一下:

我遇到了相反的问题:我已将 this live plotting solution 改编为使用 PySide2,但自然首先尝试使用 PyQt5。适应 PySide2 后,运行单个脚本失败,出现与 OP 提到的相同的错误。但是,当将窗口类导入另一个模块并在那里创建它时,一切正常。

对我有用的是从环境中删除 PyQt5,即

pip uninstall PyQt5

之后,单独运行脚本再次起作用。

编辑:我刚刚重新访问了我的代码,发现更改导入顺序,以便在 matplotlib 之前导入 PySide2 也起到了作用。因此,如果 PyQt5 和 PySide2 都没有被导入,matplotlib 会检查 PyQt5 是否已安装,如果是,则将其用作后端。

不工作

import matplotlib
from matplotlib.animation import TimedAnimation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.lines import Line2D

from PySide2 import QtWidgets

工作

from PySide2 import QtWidgets

import matplotlib
from matplotlib.animation import TimedAnimation
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.lines import Line2D

【讨论】:

【参考方案3】:

我遇到了同样的问题。这对我有用

conda uninstall matplotlib
pip install matplotlib

【讨论】:

OP 使用 Conda 吗?

以上是关于使用 PyInstaller 后 FigureCanvas 未解释为 QtWidget的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyinstaller 打包后 Kivy 应用程序崩溃

由于窗口问题,Kivy 应用程序在使用 pyinstaller 打包后崩溃

使用 PyInstaller 后 FigureCanvas 未解释为 QtWidget

使用 PyInstaller 编译得到 pyodbc 后如何在启动时修复错误?

Pyinstaller - 编译应用程序后找不到 libmagic

使用 pyinstaller 编译 python 脚本后没有名为 'scipy.spatial.transform._rotation_groups 的模块