简体   繁体   中英

How to transfer parameters from PyQt5 QSpinBox to Matplotlib?

The original code is from: https://github.com/boxcontrol/matplotlibPyQt5/blob/master/matplotlibPyQt5.py

I made some changes to the code, the code now is as followings.

import sys
import random
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget, QSpinBox

from numpy import arange, sin, pi
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class MyMplCanvas(FigureCanvas):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        # We want the axes cleared every time plot() is called
        # self.axes.hold(False)

        self.compute_initial_figure()

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                QSizePolicy.Expanding,
                QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass

class MyStaticMplCanvas(MyMplCanvas):
    """Simple canvas with a sine plot."""
    def compute_initial_figure(self):
        t = arange(0.0, 3.0, 0.01)
        s = sin(2*pi*t)  # by clicking the QSpinBox, this line should be like s = sin(value_from_QSpinBox * pi * t)
        self.axes.plot(t, s)


class ApplicationWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")

        self.file_menu = QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.fileQuit,
                QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.main_widget = QWidget(self)

        self.sb = QSpinBox(self)
        self.sb.setMinimum(1)
        self.sb.setMaximum(10)
        self.sb.setSingleStep(1)
        self.sb.setValue(1)
        self.sb.resize(self.sb.sizeHint())

        l = QVBoxLayout(self.main_widget)
        sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        l.addWidget(self.sb)
        l.addWidget(sc)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.statusBar().showMessage("All hail matplotlib!", 2000)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    aw = ApplicationWindow()
    aw.setWindowTitle("PyQt5 Matplot Example")
    aw.show()
    app.exec_()

There is a QSpinBox and a matplotlib-diagram in the window. By changing the value of the QSpinBox, I want to change the matplotlib-diagram.

To be exactly, the following line should take parameters from the QSpinBox, and the sin-diagram should be updated accordingly.

s = sin(2*pi*t)  # by clicking the QSpinBox, this line should be like s = sin(value_from_QSpinBox * pi * t)

I have tried a lot on my own but they all failed. Could anybody please help me out? Thanks a lot!

You have to use the valueChanged signal of the QSpinBox , for this you must modify the function performed by the plot as I show you:

import sys
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore, QtWidgets
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure


class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        self.axes.plot()
        FigureCanvas.setSizePolicy(self,
                QtWidgets.QSizePolicy.Expanding,
                QtWidgets.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)


class MyStaticMplCanvas(MyMplCanvas):
    """Simple canvas with a sine plot."""
    def update_figure(self, f):
        self.axes.cla()
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(f*np.pi*t)
        self.axes.plot(t, s)
        self.draw()


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("application main window")

        self.file_menu = QtWidgets.QMenu('&File', self)
        self.file_menu.addAction('&Quit', self.close,QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.file_menu)

        self.main_widget = QtWidgets.QWidget()
        l = QtWidgets.QVBoxLayout(self.main_widget)

        self.sb = QtWidgets.QSpinBox(minimum=1, maximum=10, singleStep=1, value=1)
        sc = MyStaticMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        self.sb.valueChanged.connect(sc.update_figure)
        sc.update_figure(self.sb.value())

        l.addWidget(self.sb)
        l.addWidget(sc)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)
        self.statusBar().showMessage("All hail matplotlib!", 2000)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    aw = ApplicationWindow()
    aw.setWindowTitle("PyQt5 Matplot Example")
    aw.show()
    sys.exit(app.exec_())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM