使用Qt设计器窗体和PyQt5在QWidget中绘制matplotlib图形

2024-05-15 22:31:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我不知道将matplotlib图形链接到从Qt设计器创建的表单的最佳方法。我在QtDesigner中创建了一个表单,然后通过pyuic5编译成python。我的主要计划是:

import app_framework as af
import matplotlib
from PyQt5 import QtWidgets
import sys

matplotlib.use('Qt5Agg')

app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()

其中myApp调用从Qt设计器创建的app_framework.py表单,然后由pyuic5(design.py)转换:

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       <button initializations>
       <function definitions for button callbacks>

在这个框架中,我不知道在哪里可以将matplotlib图形链接到QtDesigner中预先制作好的空小部件,或者类似的东西,以便在发生事情时在GUI窗口中绘制新数据(输入文本、按钮等)

我在这里找到了一些关于SOmatplotlib's site的线程,但是我不确定我是否理解在Qt设计器窗体中为这个小部件创建空间,然后链接绘图和/或创建小部件post hoc,然后链接和绘图的正确过程。

到目前为止,我所做的是在Qt Creator中创建一个空的QWidget,然后在pyuic5编译之后,我修改design.py文件如下:

from PyQt5 import QtCore, QtGui, QtWidgets

# **** ADDED THIS
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
# **** 

class Ui_mainWindow(object):
    def setupUi(self, mainWindow):
        <mainWindow setup stuff>
        self.centralwidget = QtWidgets.QWidget(mainWindow)

        # ****ALTERED THIS FROM self.plotWidget = QtWidgets.QWidget(self.centralWidget)
        self.plotWidget = MplWidget(self.centralWidget)
        # ***** 

        self.plotWidget.setGeometry(QtCore.QRect(20, 250, 821, 591))
        self.plotWidget.setObjectName("plotWidget")

  # **** ADDED THIS 
class MplCanvas(Canvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        Canvas.__init__(self, self.fig)
        Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)


class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
 # ***********

然后将app_framework.py设置为:

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       self.setupUi(self)
       self.pushButton_plotData.clicked.connect(self.plot_data)

    def plot_data(self):
        x=range(0, 10)
        y=range(0, 20, 2)
        self.plotWidget.canvas.ax.plot(x, y)
        self.plotWidget.canvas.draw()

我原以为这样可以,但当我点击绘图按钮时,什么也没发生。它不会锁起来,只是没有任何阴谋。我猜我遗漏了在这个空小部件中绘制matplotlib图形和/或画布的一些基本内容。


Tags: fromimportselfappmatplotlibinit链接def
1条回答
网友
1楼 · 发布于 2024-05-15 22:31:29

我通过这个SO post找到了解决方案,这个free sample chapter链接到我可能需要购买的一本书。正如在许多其他帖子中提到的一样,需要使用头MPLWIDGET“将空白QtWIDGET”推广到MPLWIDGET。执行此操作后,然后运行pyuic5命令,“from mplwidget import mplwidget”将出现在design.py文件中,该文件可以随时更新,而无需担心覆盖问题。然后,使用以下命令创建mplwidget.py文件:

# Imports
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
import matplotlib

# Ensure using PyQt5 backend
matplotlib.use('QT5Agg')

# Matplotlib canvas class to create figure
class MplCanvas(Canvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        Canvas.__init__(self, self.fig)
        Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)

# Matplotlib widget
class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)   # Inherit from QWidget
        self.canvas = MplCanvas()                  # Create canvas object
        self.vbl = QtWidgets.QVBoxLayout()         # Set box for plotting
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)

然后,应用程序框架可以像我之前一样。当运行并按下绘图按钮时,该图将按预期显示。我想我基本上已经做了所有手工“提升”QWidget的工作,只是缺少了vbl的东西,但是每次Qt设计器表单被编辑时,所有这些都会被覆盖。

app_framework.py版本:

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       self.setupUi(self)
       self.pushButton_plotData.clicked.connect(self.plot_data)

    def plot_data(self):
        x=range(0, 10)
        y=range(0, 20, 2)
        self.plotWidget.canvas.ax.plot(x, y)
        self.plotWidget.canvas.draw()

主.py:

from PyQt5 import QtWidgets
import sys

# Local Module Imports
import app_framework as af

# Create GUI application
app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()

相关问题 更多 >