Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:12:06

0001 import matplotlib
0002 
0003 matplotlib.use("QtAgg")
0004 
0005 from PyQt5 import QtCore, QtWidgets, QtGui
0006 
0007 from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg, NavigationToolbar2QT
0008 from matplotlib.figure import Figure
0009 import matplotlib.pyplot as plt
0010 
0011 from PyQt5 import QtCore, QtWidgets
0012 
0013 
0014 class MatplotlibWidget(QtWidgets.QWidget):
0015     """
0016     This widget is supposed to support a processor that renders its output to
0017     a matplotlib figure.
0018     For performance reasons, it only renders the content if the widget is_active.
0019     """
0020 
0021     def __init__(self, processor, parent=None):
0022         super(MatplotlibWidget, self).__init__()
0023         self.processor = processor
0024         self.fig, self.axes = processor.get_figure_axes()
0025 
0026         self.canvas = FigureCanvasQTAgg(self.fig)
0027         toolbar = NavigationToolbar2QT(self.canvas, self)
0028 
0029         self.layout = QtWidgets.QVBoxLayout()
0030         self.layout.addWidget(toolbar)
0031         self.layout.addWidget(self.canvas)
0032         self.setLayout(self.layout)
0033 
0034         self.is_active = False
0035 
0036     def change_step(self, step):
0037         try:
0038             for ax in self.axes.flatten():
0039                 ax.cla()
0040         except:
0041             self.axes.cla()
0042 
0043         if self.is_active:
0044             self.processor.draw(self.fig, self.axes, step)
0045             self.canvas.draw()
0046 
0047 
0048 class LogWidget(QtWidgets.QTextEdit):
0049     """
0050     This is a widget dedicated to rendering the log
0051     of a certain step.
0052     """
0053 
0054     def __init__(self, steps, parent=None):
0055         super(LogWidget, self).__init__()
0056         self.steps = steps
0057 
0058         font = QtGui.QFont()
0059         font.setFamily("monospace [Consolas]")
0060         font.setFixedPitch(True)
0061         font.setStyleHint(QtGui.QFont.TypeWriter)
0062 
0063         self.setFont(font)
0064         self.setReadOnly(True)
0065         self.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
0066 
0067     def change_step(self, step):
0068         if step >= len(self.steps):
0069             self.setText(f"Error: cannot display log for step {step}")
0070         else:
0071             self.setText("".join(self.steps[step]))
0072 
0073 
0074 class MainWindow(QtWidgets.QWidget):
0075     """
0076     This is the main window. It sets the gui up etc.
0077     Most importantly, it calls .step_changed() on the active tab-widget
0078     if the step-slider has changed
0079     """
0080 
0081     def __init__(self, processors, steps, *args, **kwargs):
0082         super(MainWindow, self).__init__(*args, **kwargs)
0083         self.setWindowTitle("GSF Debugger")
0084 
0085         layout = QtWidgets.QVBoxLayout()
0086 
0087         # Step label
0088         self.label = QtWidgets.QLabel("step: 0", self)
0089         layout.addWidget(self.label)
0090 
0091         # Slider
0092         self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
0093         self.slider.setMinimum(0)
0094         self.slider.setMaximum(len(steps))
0095         self.slider.valueChanged.connect(self.step_changed)
0096 
0097         def disable():
0098             for p in self.processor_widgets:
0099                 if hasattr(p, "is_active"):
0100                     p.is_active = False
0101 
0102         self.slider.sliderPressed.connect(disable)
0103 
0104         def switch(i=None):
0105             if i is None:
0106                 i = self.tabs.currentIndex()
0107             for p in self.processor_widgets:
0108                 if hasattr(p, "is_active"):
0109                     p.is_active = False
0110             if hasattr(self.processor_widgets[i], "is_active"):
0111                 self.processor_widgets[i].is_active = True
0112             self.step_changed()
0113 
0114         self.slider.sliderReleased.connect(switch)
0115 
0116         def bwd():
0117             self.slider.setValue(max(self.slider.value() - 1, 0))
0118             self.step_changed()
0119 
0120         bwdBtn = QtWidgets.QPushButton("-")
0121         bwdBtn.pressed.connect(bwd)
0122 
0123         def fwd():
0124             self.slider.setValue(min(self.slider.value() + 1, len(steps)))
0125             self.step_changed()
0126 
0127         fwdBtn = QtWidgets.QPushButton("+")
0128         fwdBtn.pressed.connect(fwd)
0129 
0130         hlayout = QtWidgets.QHBoxLayout()
0131         hlayout.addWidget(bwdBtn, 1)
0132         hlayout.addWidget(self.slider, 18)
0133         hlayout.addWidget(fwdBtn, 1)
0134 
0135         layout.addLayout(hlayout)
0136 
0137         # Tabs
0138         self.processor_widgets = []
0139         self.tabs = QtWidgets.QTabWidget(self)
0140         for p in processors:
0141             self.processor_widgets.append(MatplotlibWidget(p))
0142             self.tabs.addTab(self.processor_widgets[-1], p.name())
0143 
0144         self.processor_widgets.append(LogWidget(steps))
0145         self.tabs.addTab(self.processor_widgets[-1], "Log")
0146         self.tabs.currentChanged.connect(switch)
0147 
0148         layout.addWidget(self.tabs)
0149 
0150         # init
0151         switch(0)
0152         self.step_changed()
0153 
0154         # Finalize
0155         self.setLayout(layout)
0156         self.show()
0157 
0158     def step_changed(self):
0159         self.label.setText(f"step: {self.slider.value()}")
0160         for w in self.processor_widgets:
0161             w.change_step(self.slider.value())