PYQT 结合 Matplotlib 报错 FigureCanvasQTAgg 无法转换成 QWidget

PYQT 结合 Matplotlib 报错

大家好,我在PYQT 结合 Matplotlib 时报错,错误如下:
vertical_layout.addWidget(window.canvas)
TypeError: addWidget(self, a0: QWidget, stretch: int = 0, alignment: Union[Qt.Alignment, Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type 'FigureCanvasQTAgg'
python-BaseException
Backend Qt5Agg is interactive backend. Turning interactive mode on.

似乎是 FigureCanvasQTAgg 无法转换成 QWidget 导致的。

以下是源代码:

import matplotlib
from PyQt5 import QtWidgets, QtCore
import matplotlib
from PyQt5.QtWidgets import QVBoxLayout
from matplotlib.figure import Figure

matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

def showCanvas(window):
    window.canvas = FigureCanvas(Figure())
    window.clb = []
    window.plot = []

    vertical_layout = QVBoxLayout()
    vertical_layout.addWidget(window.canvas)

    pass

以下是调用这个方法的代码:

class ChartCanvsPageControl(ChartCanvasPage.Ui_MainWindow, QMainWindow):
    formId = CommonValueUtils.ForestFarmWages_DetailCode
    def __init__(self,formId):
        super(ChartCanvasPage.Ui_MainWindow, self).__init__()
        # 创建界面
        self.setupUi(self)
        self.formId = formId
        ComponentUtils.initWindow(self)
        CanvsUtils.showCanvas(self)

参考gpt:
结合自己分析给你如下建议:
1.代码中混用了PyQt和PySide两个不兼容的库,导致类型转换出错。您应该只使用其中一个库,并保持一致。
2.代码中没有正确地继承FigureCanvas类,导致无法作为QWidget添加到布局中。您应该使用super方法来调用父类的初始化函数,并设置合适的尺寸策略和更新几何形状。

是不是这样


import matplotlib
from PyQt5 import QtWidgets
import matplotlib
from PyQt5.QtWidgets import QVBoxLayout, QWidget
from matplotlib.figure import Figure

matplotlib.use("Qt5Agg")
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

def showCanvs(window):
    window.canvas = FigureCanvas(Figure())
    window.clb = []
    window.plot = []

    container = QWidget()  # 创建一个 QWidget 容器
    vertical_layout = QVBoxLayout(container)  # 将容器添加到 QVBoxLayout 中
    vertical_layout.addWidget(window.canvas)  # 将 FigureCanvas 添加到容器中

    window.setCentralWidget(container)  # 设置容器为窗口的中心部件

    pass

参考:https://blog.csdn.net/qin_liang/article/details/127018270

该回答引用gpt
您可以尝试将 FigureCanvasQTAgg 对象添加到一个 QWidget 的布局中,然后再将该 QWidget 添加到 QVBoxLayout 中,如下所示:

from PyQt5.QtWidgets import QWidget

canvas_widget = QWidget()
canvas_widget.setLayout(QVBoxLayout())
canvas_widget.layout().addWidget(window.canvas)

vertical_layout.addWidget(canvas_widget)

这样就可以将 FigureCanvasQTAgg 对象转换为 QWidget 对象后添加到布局中了。

FigureCanvasQTAgg 是 Matplotlib 绘图的一个特定类型的窗口,它不能直接添加到 PyQt 的布局中

诸位的方法都试过了,addWidget 还是报这个错误:

```python
TypeError: addWidget(self, a0: QWidget, stretch: int = 0, alignment: Union[Qt.Alignment, Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type 'FigureCanvasQTAgg'
python-BaseException

```

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇博客: matplotlib.backends.backend_qt5agg.FigureCanvasQTagg构成及用法中的 Reference 部分也许能够解决你的问题。
  • 以下回答由chatgpt基于相关博客总结生成:

    问题的根本原因是FigureCanvasQTAgg对象无法直接转换为QWidget对象。因此,解决这个问题的方法是将FigureCanvasQTAgg对象放置到一个中间的QWidget对象中,然后将这个QWidget对象添加到垂直布局中。

    以下是修改后的示例代码:

    import matplotlib
    from PyQt5 import QtWidgets, QtCore
    import matplotlib
    from PyQt5.QtWidgets import QVBoxLayout, QWidget
    from matplotlib.figure import Figure
    
    matplotlib.use("Qt5Agg")
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    
    def showCanvs(window):
        window.canvas = FigureCanvas(Figure())
        window.clb = []
        window.plot = []
    
        # 创建一个中间的QWidget对象
        canvas_container = QWidget()
    
        # 创建一个垂直布局,并将中间的QWidget对象添加到布局中
        vertical_layout = QVBoxLayout()
        vertical_layout.addWidget(canvas_container)
    
        # 创建一个水平布局,并将FigureCanvasQTAgg对象添加到中间的QWidget对象中
        horizontal_layout = QHBoxLayout(canvas_container)
        horizontal_layout.addWidget(window.canvas)
    
        pass
    

    使用以上代码,将FigureCanvasQTAgg对象放置到一个QWidget对象中,再将这个QWidget对象添加到垂直布局中,即可解决报错。

    希望能够帮助到你!如果你还有其他问题,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^