Python 对话框页面上 QWidget 中的 Pyplot (matplotlib) 绘图

问题描述 投票:0回答:1

我有一个已经运行了一年多的应用程序。我添加了一个新部分。此部分在按下按钮时打开一个对话框。在这个对话框中,我放置了一个平淡的 QWidget。我想在该小部件上使用 matplotlib 进行绘图。下面我将展示我尝试用作基础的内容。我无法完成这项任务。我举的许多示例根本不起作用 - 即当我运行应用程序时,我收到方法不存在的消息。在某些情况下,我修复了这些编程错误,然后绘图在另一个窗口中打开,但不是我希望它打开的位置。 有没有一种人道的方式将 matplotlib 图放在 qwidget 上?如果没有,我该怎么做才能在那里得到一个情节。我几乎要宣布这是不可能的。请指出我正确的方向。我正在尝试在 python3 中执行此操作 - 而不是在 python2 中 - 编写示例的方式可能来自 python2,也许示例已经过时了。

我看了

1- 使用 Qt Designer 表单和 PyQt5 在 QWidget 中绘制 matplotlib 图形。注意,我直接使用 pyside2 而不是 qt5。

2- https://www.pythonguis.com/tutorials/pyside-plotting-matplotlib/

3- https://forum.pythonguis.com/t/embed-a-matplotlib-graph-in-a-specific-widget-Design-with-designer/1066

注意-我的 qwidget 不是“中央小部件”,它是我在 qt-designer 中特定位置定义的特定小部件。最后还会有好几个这样的。

我希望我能找到一种在我想绘制的地方绘制的方法。最终,这并没有奏效。要么我出错了,要么绘图是在打开的新窗口中绘制的。

此代码:我编辑了代码 - 对于打印感到抱歉,这是我知道我在哪里的方式:

from PySide2.QtWidgets import *
import PySide2.QtWidgets as QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
from matplotlib.figure import Figure
import matplotlib
matplotlib.use('Qt5Agg')


class MplCanvas(Canvas):
    '''
    Class to represent the FigureCanvas widget
    '''
    def __init__(self):
        print('7')
        self.fig = Figure()
        print('8')
        self.ax = self.fig.add_subplot(111)
        print('9')
        super(MplCanvas, self).__init__(self.fig)
        print('10')
        #Canvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)
        print('11')
        Canvas.updateGeometry(self)
        print('12')




class MplWidget(QWidget):
    '''
    Widget promoted and defined in Qt Designer
    '''
    def __init__(self, parent=None):
        #QWidget.__init__(self, parent)
        super(MplWidget, self).__init__(parent)
        print('1')
        self.vbl = QVBoxLayout()
        print('2')
        #self.canvas = Canvas(Figure())
        print('3')
        self.canvas = MplCanvas()
        print('3.5')
        self.vbl.addWidget(self.canvas)
        #self.vbl.addWidget(parent)
        print('4')
        self.setLayout(self.vbl)
        print('5')
        self.checkCanvas()
        print('5')

    def checkCanvas(self):
        print(self.canvas)

    def getCanvas(self):
        return self.canvas

当我只运行构造函数时: plotWidget = MplWidget(self.ink_limit_master_dialog.pyplot_widget)

我打印:

1
2
3
7
8
9
10
11
12
3.5

但是然后我收到以下错误:

Traceback (most recent call last):
  File "C:/Work/ResourceGenerator/ResCreatorNewGeneration/res_create_NewGen_uic.py", line 1109, in ink_limit_master_callback
    plotWidget = MplWidget(self.ink_limit_master_dialog.pyplot_widget)
  File "C:\Work\ResourceGenerator\ResCreatorNewGeneration\MplWidgetClass.py", line 70, in __init__
    self.vbl.addWidget(self.canvas)
TypeError: 'PySide2.QtWidgets.QBoxLayout.addWidget' called with wrong argument types:
  PySide2.QtWidgets.QBoxLayout.addWidget(MplCanvas)
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)

基本上我无法将 MplCanvas 添加为小部件。

似乎将 matplotlib 附加到 qwidget 并不简单......

matplotlib qt5 pyside2 qwidget
1个回答
0
投票

答案有两部分。首先,我定义 MplCanvas 和 MplWidget 的方式是有效的,但对于高于我所拥有的版本的 matplotlib,因此无需详细说明,这需要针对我的 matplotlib 版本进行稍微更改。但这不是问题的本质。我使用 qt 设计器和 PyPlot2 编写了我的项目 gui。事实上,对于 gui 本身,我使用了正确的脚本 pyplot-uic 将 ui 转换为 python 代码。当我编写一个独立项目并尝试在主窗口中的小部件上绘制 pyplot 图形时,setLayout 突然没有给出输入类型不正确的错误。但是,当我使用资源(qrc)将图标添加到主窗口时,返回了错误。我注意到我使用了qt脚本将资源arc文件转换为python文件。因此,这个 python 文件导入了 qt 而不是 pyside2 对象。由于资源导入几乎是在一开始,这确实导致了 pyqt 和 pyside2 之间的混淆 - 正如前面所说,它们是不兼容的。当我使用 pyside2 脚本 (pyside2-rcc) 重新运行从资源到 python 文件的转换时,python 文件从 pyside2 导入对象。现在 pyside2 和 pyqt 不再混淆,因此不兼容性消失了,一切(再次更改类以与我的 matplotlib 版本兼容)都有效。我成功地将 qwidget“windows”放在对话框上,并通过 qt-designer 使用图标,并且一切正常,包括在 qwidget 窗口上绘制 matplotlib-pyplot“图”。如果有人有兴趣了解我是如何做到这一点的,我可以提供代码。我试图在这里保持简短,所以我没有发布一堆代码。底线是——这确实有效。如果它不起作用,那么问题通常是 pyqt 和 pyside2 无法共存,因此有时需要在代码行为异常的情况下寻找和搜索 pyqt 导入。就我而言,这是从 qrc 到 python 的错误转换 - 与在整个代码中使用 pyside2 和 qt 的愿望不一致。

© www.soinside.com 2019 - 2024. All rights reserved.