from PyQt5.QtWidgets import QWidget, QPushButton, QSizePolicy, QLineEdit,\ QMessageBox, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QFrame,\ QDoubleSpinBox, QComboBox, QSpinBox from PyQt5.QtCore import pyqtSlot import numpy as np from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from DataProvider import DataProvider class SpikeRedetectGui(QWidget): def __init__(self, data_provider: DataProvider): super().__init__() self.data_provider = data_provider self.title = 'Spike Redetection' self.left = 10 self.top = 10 self.width = 640 self.height = 400 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # Middle: middle = QHBoxLayout() # Canvas Area for matplotlib figure plot_area = QFrame() plot_area_layout = QVBoxLayout() m = PlotCanvas(self) m.move(0, 0) plot_area_layout.addWidget(m) # plot area buttons plot_area_buttons = QFrame() plot_area_buttons_layout = QHBoxLayout() plot_area_buttons.setLayout(plot_area_buttons_layout) plot_area_layout.addWidget(plot_area_buttons) button = QPushButton('Button1', self) button.setToolTip('A nice button!') button.clicked.connect(lambda: threshold_spinbox.setValue(1)) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) plot_area_buttons_layout.addWidget(button) button = QPushButton('Button2', self) button.setToolTip('Another nice button!') button.clicked.connect(lambda: threshold_spinbox.setValue(2)) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) plot_area_buttons_layout.addWidget(button) button = QPushButton('Button3', self) button.setToolTip('Even more nice buttons!') button.clicked.connect(lambda: threshold_spinbox.setValue(3)) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) plot_area_buttons_layout.addWidget(button) button = QPushButton('Button4', self) button.setToolTip('Even more nice buttons!') button.clicked.connect(lambda: threshold_spinbox.setValue(4)) button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) plot_area_buttons_layout.addWidget(button) plot_area.setLayout(plot_area_layout) middle.addWidget(plot_area) middle.addWidget(QVLine()) # Side (options) panel panel = QFrame() panel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) panel.setMaximumWidth(200) panel_layout = QVBoxLayout() stim_val_label = QLabel("Stimulus value:") self.stim_val_box = QComboBox() repro_label = QLabel("Repro:") panel_layout.addWidget(repro_label) self.repro_box = QComboBox() self.repro_box.currentTextChanged.connect(self.repro_change) for repro in self.data_provider.get_repros(): self.repro_box.addItem(repro) panel_layout.addWidget(self.repro_box) panel_layout.addWidget(stim_val_label) panel_layout.addWidget(self.stim_val_box) trial_label = QLabel("Trial:") panel_layout.addWidget(trial_label) threshold_spinbox = QSpinBox(self) threshold_spinbox.setValue(1) threshold_spinbox.setSingleStep(1) threshold_spinbox.valueChanged.connect() panel_layout.addWidget(threshold_spinbox) filler = QFill(minh=200) panel_layout.addWidget(filler) self.status_label = QLabel("Done x/15 Stimulus Values") panel_layout.addWidget(self.status_label) filler = QFill() panel_layout.addWidget(filler) threshold_label = QLabel("Threshold:") panel_layout.addWidget(threshold_label) threshold_spinbox = QDoubleSpinBox(self) threshold_spinbox.setValue(1) threshold_spinbox.setSingleStep(0.5) threshold_spinbox.valueChanged.connect(lambda: m.plot(threshold_spinbox.value())) panel_layout.addWidget(threshold_spinbox) button = QPushButton('Accept!', self) button.setToolTip('Accept the threshold for current stimulus value') panel_layout.addWidget(button) panel.setLayout(panel_layout) middle.addWidget(panel) self.setLayout(middle) self.show() @pyqtSlot() def repro_change(self): repro = self.repro_box.currentText() self.stim_val_box.clear() for val in self.data_provider.get_stim_values(repro): self.stim_val_box.addItem(str(val)) class PlotCanvas(FigureCanvas): def __init__(self, parent=None, dpi=100): fig = Figure(dpi=dpi) self.axes = fig.add_subplot(111) FigureCanvas.__init__(self, fig) self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) self.plot() @pyqtSlot() def plot(self, mean=1): x = np.arange(0, 1, 0.0001) data = np.sin(x*np.pi*2*mean) ax = self.axes ax.clear() ax.plot(x, data, 'r-') ax.set_title('Sinus Example') self.draw() class QHLine(QFrame): def __init__(self): super(QHLine, self).__init__() self.setFrameShape(QFrame.HLine) self.setFrameShadow(QFrame.Sunken) class QVLine(QFrame): def __init__(self): super(QVLine, self).__init__() self.setFrameShape(QFrame.VLine) self.setFrameShadow(QFrame.Sunken) class QFill(QFrame): def __init__(self, maxw=int(2**24)-1, maxh=int(2**24)-1, minw=0, minh=0): super(QFill, self).__init__() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setMaximumSize(maxw, maxh) self.setMinimumSize(minw, minh)