def __init__(self, parent, title, var, func, args): super(VarGrapher, self).__init__(parent) self.setFixedSize(700, 600) self.setWindowTitle(title) # Figure panel self._figure = matplotlib.figure.Figure() self._canvas = backend.FigureCanvasQTAgg(self._figure) self._toolbar = backend.NavigationToolbar2QT(self._canvas, self) # Variable panel self._variable_widget = QtWidgets.QWidget() # Button panel self._button_widget = QtWidgets.QWidget() # Central widget layout = QtWidgets.QVBoxLayout() layout.addWidget(self._canvas) layout.addWidget(self._toolbar) layout.addWidget(self._variable_widget) layout.addWidget(self._button_widget) self.setLayout(layout) # Get function handle, information object self._func = func self._args = args self._var = var # Variable ranges grid = QtWidgets.QGridLayout() self._bounds = {} for k, lhs in enumerate(self._args): var = lhs.var() # Guess appropriate bounds if var.label() == 'membrane_potential' or \ var.name().lower() in ['v', 'voltage', 'potential']: if var.unit() == myokit.units.volt: lohi = (-0.1, 0.1) else: lohi = (-100.0, 100.0) else: v = lhs.eval() if v >= 0 and v <= 1: lohi = (0.0, 1.0) elif v < 0: lohi = (-50, 50) else: lohi = (0, 100) # Row and column of first widget in grid row = k // 2 col = (k % 2) * 3 # Add label label = QtWidgets.QLabel(var.qname()) grid.addWidget(label, row, col) # Add lower and upper bound or single value if k < 2: # Lower editlo = QtWidgets.QLineEdit() editlo.setValidator(QtGui.QDoubleValidator()) editlo.setText(str(lohi[0])) grid.addWidget(editlo, row, col + 1) # Upper edithi = QtWidgets.QLineEdit() edithi.setValidator(QtGui.QDoubleValidator()) edithi.setText(str(lohi[1])) grid.addWidget(edithi, row, col + 2) self._bounds[lhs] = (editlo, edithi) else: # Single, fixed value v = 0.5 * (lohi[0] + lohi[1]) edit = QtWidgets.QLineEdit(str(v)) edit.setReadOnly(True) grid.addWidget(edit, row, col + 1) self._bounds[lhs] = (edit, edit) self._variable_widget.setLayout(grid) # Buttons layout = QtWidgets.QHBoxLayout() # Graph button button = QtWidgets.QPushButton('Refresh') button.clicked.connect(self.action_draw) layout.addWidget(button) # Close button button = QtWidgets.QPushButton('Close') button.clicked.connect(self.close) layout.addWidget(button) self._button_widget.setLayout(layout) # Draw! self.action_draw()
def __init__(self, filename=None): super(DataBlockViewer, self).__init__() # Set application icon self.setWindowIcon(icon()) # Set size, center self.resize(800, 600) self.setMinimumSize(600, 400) qr = self.frameGeometry() cp = QtWidgets.QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) # Status bar self._label_cursor = QtWidgets.QLabel() self.statusBar().addPermanentWidget(self._label_cursor) self.statusBar().showMessage('Ready') # Menu bar self.create_menu() # Timer self._timer_interval = 50 self._timer = QtCore.QTimer(self) self._timer.setInterval(self._timer_interval) self._timer.setSingleShot(False) self._timer.timeout.connect(self.action_next_frame) self._timer_paused = False try: self._timer.setTimerType(Qt.PreciseTimer) except AttributeError: pass # Qt4 uses precise timer by default # Video widget self._video_scene = VideoScene() self._video_scene.mouse_moved.connect(self.event_mouse_move) self._video_scene.single_click.connect(self.event_single_click) self._video_scene.double_click.connect(self.event_double_click) self._video_view = VideoView(self._video_scene) #self._video_view.setViewport(QtOpenGL.QGLWidget()) self._video_pixmap = None self._video_item = None self._video_frames = None self._video_iframe = None self._colormap_pixmap = None self._colormap_item = None # Video slider self._slider = QtWidgets.QSlider(Qt.Horizontal) self._slider.setTickPosition(QtWidgets.QSlider.NoTicks) #self._slider.setTickPosition(QtWidgets.QSlider.TicksBothSides) self._slider.setSingleStep(1) self._slider.setMinimum(0) self._slider.setMaximum(0) self._slider.sliderPressed.connect(self.action_pause_timer) self._slider.sliderReleased.connect(self.action_depause_timer) self._slider.valueChanged.connect(self.action_set_frame) # Controls style = QtWidgets.QApplication.style() # Play button self._play_icon_play = style.standardIcon(style.SP_MediaPlay) self._play_icon_pause = style.standardIcon(style.SP_MediaPause) self._play_button = QtWidgets.QPushButton() self._play_button.setIcon(self._play_icon_play) self._play_button.pressed.connect(self.action_start_stop) # Frame indicator self._frame_label = QtWidgets.QLabel('Frame') self._frame_field = QtWidgets.QLineEdit('0') self._frame_field.setReadOnly(True) self._frame_field.setMaxLength(6) self._frame_field.setMaximumWidth(100) self._frame_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) # Time indicator self._time_label = QtWidgets.QLabel('Time') self._time_field = QtWidgets.QLineEdit('0') self._time_field.setReadOnly(True) self._time_field.setMaxLength(6) self._time_field.setMaximumWidth(100) self._time_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) # Speed indicator self._rate_label = QtWidgets.QLabel('Delay') self._rate_field = QtWidgets.QLineEdit(str(self._timer_interval)) self._rate_field.setValidator(QtGui.QIntValidator(1, 2**20, self)) self._rate_field.editingFinished.connect(self.event_rate_changed) self._rate_field.setMaximumWidth(100) self._rate_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter) # Graph controls self._graph_clear_button = QtWidgets.QPushButton('Clear graphs') self._graph_clear_button.pressed.connect(self.action_clear_graphs) # Variable selection self._variable_select = QtWidgets.QComboBox() self._variable_select.activated.connect(self.event_variable_selected) self._variable_select.setMinimumWidth(120) # Colormap selection self._colormap = myokit.ColorMap.names().next() self._colormap_select = QtWidgets.QComboBox() for cmap in myokit.ColorMap.names(): self._colormap_select.addItem(cmap) self._colormap_select.activated.connect(self.event_colormap_selected) self._colormap_select.setMinimumWidth(120) # Control layout self._control_layout = QtWidgets.QHBoxLayout() self._control_layout.addWidget(self._play_button) self._control_layout.addWidget(self._frame_label) self._control_layout.addWidget(self._frame_field) self._control_layout.addWidget(self._time_label) self._control_layout.addWidget(self._time_field) self._control_layout.addWidget(self._rate_label) self._control_layout.addWidget(self._rate_field) self._control_layout.addWidget(self._graph_clear_button) self._control_layout.addWidget(self._variable_select) self._control_layout.addWidget(self._colormap_select) # Graph area self._graph_area = GraphArea() self._graph_area.mouse_moved.connect(self.event_mouse_move) # Video Layout self._video_layout = QtWidgets.QVBoxLayout() self._video_layout.addWidget(self._video_view) self._video_layout.addWidget(self._slider) self._video_layout.addLayout(self._control_layout) self._video_widget = QtWidgets.QWidget() self._video_widget.setLayout(self._video_layout) # Central layout self._central_widget = QtWidgets.QSplitter(Qt.Vertical) self._central_widget.addWidget(self._video_widget) self._central_widget.addWidget(self._graph_area) self.setCentralWidget(self._central_widget) # Current path, current file, recent files self._path = QtCore.QDir.currentPath() self._file = None self._recent_files = [] # Current data block, display variable self._data = None self._variable = None # Load settings from ini file self.load_config() self.update_window_title() # Set controls to correct values self._colormap_select.setCurrentIndex( self._colormap_select.findText(self._colormap)) self._rate_field.setText(str(self._timer_interval)) self._timer.setInterval(self._timer_interval) # Pause video playback during resize self._resize_timer = QtCore.QTimer() self._resize_timer.timeout.connect(self._resize_timeout) self._video_view.resize_event.connect(self._resize_started) # Attempt to load selected file if filename and os.path.isfile(filename): self.load_data_file(filename)