Pyqt 多參數控制繪圖 採用spinbox 和horizionslider 控制sin曲線的幅值和相位的變換。
主程序如下:
# -*- coding: utf-8 -*-
import sys
import os
import random
import time
import numpy as np
import matplotlib
matplotlib.use("Qt5Agg")
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from numpy import arange
import pandas as pd
import ControlCanvas
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
self.screen = QtWidgets.QDesktopWidget().screenGeometry()
MainWindow.setGeometry(10, 50, self.screen.width()/4,self.screen.height()/4)
# MainWindow.resize(self.screen.width()/4,self.screen.height()/4)
# MainWindow.showMaximized()
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
MainWindow.setCentralWidget(self.centralWidget)
self.testing = [0,0]
####################################################################################
#QGridLayout
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.gridLayout.setSpacing(2)
self.gridLayout.setObjectName("gridLayout")
#splitter
self.splitter = QtWidgets.QSplitter(orientation=QtCore.Qt.Horizontal)
self.gridLayout.addWidget(self.splitter,1,0,8,0)
self.splitter.setSizes([self.splitter.size().height() * 0.8, self.splitter.size().height() * 0.2])
# Canvas
self.main_widget = QWidget()
self.dc = ControlCanvas.MyControlMplCanvas(self.main_widget, width=5, height=4, dpi=100)
self.splitter.addWidget(self.dc)
# self.gridLayout.addWidget(self.dc,rowspan=-1)
#
#QVBoxLayout
self.verticallayout = QtWidgets.QVBoxLayout()
# self.verticallayout.setContentsMargins(11, 11, 11, 11)
self.verticallayout.setSpacing(6)
self.verticallayout.setObjectName("verticallayout")
self.gridLayout.addLayout(self.verticallayout, 0, 1)
#
self.lb = []
self.hs = []
self.sp = []
self.echoGroup = QtWidgets.QGroupBox('Echo')
self.echoLayout = QtWidgets.QGridLayout()
self.echoGroup.setLayout(self.echoLayout)
sp_inital_value = [0.,0.]
sp_range = [[0,9999.],[0.,500.]]
lb_name = ['a','b']
for i in range(2):
self.lb.append(i);self.hs.append(i);self.sp.append(i)
self.lb[i] = QtWidgets.QLabel(lb_name[i])
self.echoLayout.addWidget(self.lb[i],i+1,0)
self.hs[i] = QtWidgets.QSlider(self.centralWidget)
self.hs[i].setOrientation(QtCore.Qt.Horizontal)
self.hs[i].setRange(sp_range[i][0],sp_range[i][1])
self.echoLayout.addWidget(self.hs[i],i+1,2)
self.sp[i] = QtWidgets.QDoubleSpinBox()
self.sp[i].setDecimals(5)
self.sp[i].setValue(sp_inital_value[i])
self.sp[i].setSingleStep(1)
self.sp[i].setRange(sp_range[i][0],sp_range[i][1])
self.echoLayout.addWidget(self.sp[i],i+1,1)
self.hs[i].valueChanged.connect(self.sp[i].setValue)
self.sp[i].valueChanged.connect(self.hs[i].setValue)
self.hs[i].sliderReleased.connect(lambda: self.dc.update_figure(self.figure_args()))
self.sp[i].valueChanged.connect(lambda: self.dc.update_figure(self.figure_args()))
self.splitter.addWidget(self.echoGroup)
#
def figure_args(self):
return [self.sp[i].value() for i in range(2)]
####################################################################################
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = Ui_MainWindow()
w = QtWidgets.QMainWindow()
ex.setupUi(w)
w.show()
sys.exit(app.exec_())
####################################################################################
Canvas相關的控制變量
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
class MyMplCanvas(FigureCanvas):
def __init__(self, parent=None, width=50, height=50, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
# 每次plot()調用的時候,我們希望原來的座標軸被清除(所以False)
self.compute_initial_figure()
#
FigureCanvas.__init__(self, fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self,
QSizePolicy.Expanding,
QSizePolicy.Expanding)
self.axes.set_xlabel('Strain[-]')
self.axes.set_ylabel('Stress[GPa]')
FigureCanvas.updateGeometry(self)
def compute_initial_figure(self):
pass
class MyControlMplCanvas(MyMplCanvas):#
def __init__(self, *args, **kwargs):
MyMplCanvas.__init__(self, *args, **kwargs)
def compute_initial_figure(self):
self.axes.plot([0, 0, 0, 0], [1, 2, 3, 4], 'r')
def update_figure(self,*args):
print (args)
args= args[0]
a = args[0];b = args[1];
x = np.arange(0.0, 3., 0.01)
self.axes.cla()
y = self.func1(a,b,x)
self.axes.plot(x, y)
self.axes.grid('on')
self.draw()
def func1(self,a,b,x):
value = a*np.sin(x*np.pi+b)
return value