def create_graph_tab(self, time, data): """ Creates a widget displaying a time series. """ widget = QtWidgets.QWidget(self) # Create figure figure = matplotlib.figure.Figure() figure.suptitle(self._filename) canvas = backend.FigureCanvasQTAgg(figure) canvas.setParent(widget) axes = figure.add_subplot(1, 1, 1) toolbar = backend.NavigationToolbar2QT(canvas, widget) # Draw line if time is None: axes.plot(data) else: axes.plot(time, data) # Create a layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(toolbar) widget.setLayout(vbox) self._figures.append(figure) self._axes.append(axes) return widget
def create_graph_tab(self, record): """ Creates a widget displaying the data in record i """ widget = QtWidgets.QWidget(self) # Create figure figure = matplotlib.figure.Figure() figure.suptitle(self._wcp.filename()) canvas = backend.FigureCanvasQTAgg(figure) canvas.setParent(widget) axes = figure.add_subplot(1, 1, 1) toolbar = backend.NavigationToolbar2QT(canvas, widget) # Draw lines for i in range(self._wcp.channels()): axes.plot( np.array(self._wcp.times(), copy=True), np.array(self._wcp.values(record, i), copy=True), ) # Create a layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(toolbar) widget.setLayout(vbox) self._figures.append(figure) self._axes.append(axes) return widget
def create_protocol_tab(self, channel): """ Creates a widget displaying a stored D/A signal. """ widget = QtWidgets.QWidget(self) # Create figure figure = matplotlib.figure.Figure() figure.suptitle(self._abf.filename()) canvas = backend.FigureCanvasQTAgg(figure) canvas.setParent(widget) axes = figure.add_subplot(1, 1, 1) toolbar = backend.NavigationToolbar2QT(canvas, widget) # Draw lines name = 'DA(' + str(channel) + ')' # Default if no data is present times = None for i, sweep in enumerate(self._abf.protocol()): if times is None: name = 'DA' + str(sweep[channel].number()) + ': ' \ + sweep[channel].name() times = sweep[channel].times() axes.plot(times, sweep[channel].values()) # Create a layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(toolbar) widget.setLayout(vbox) self._figures.append(figure) self._axes.append(axes) return widget, name
def create_graph_tab(self, time, key): """ Creates a widget displaying a graph. """ widget = QtWidgets.QWidget(self) # Create figure figure = matplotlib.figure.Figure() figure.suptitle(self._atf.filename()) canvas = backend.FigureCanvasQTAgg(figure) canvas.setParent(widget) axes = figure.add_subplot(1, 1, 1) toolbar = backend.NavigationToolbar2QT(canvas, widget) # Draw lines axes.plot(self._atf[time], self._atf[key]) # Create a layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(toolbar) widget.setLayout(vbox) self._figures.append(figure) self._axes.append(axes) # Return widget return widget
def __init__(self, *filenames): super(DataLogViewer, self).__init__() # Set Title, icon self.setWindowTitle(TITLE + ' ' + myokit.__version__) # Set size, center self.resize(800, 600) qr = self.frameGeometry() cp = QtWidgets.QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) # Add widget for Abf file tabs self._tabs = QtWidgets.QTabWidget() self._tabs.setTabsClosable(True) self._tabs.tabCloseRequested.connect(self.action_close) self.setCentralWidget(self._tabs) # Menu bar self.create_menu() # Tool bar self.create_toolbar() # Status bar self.statusBar().showMessage('Ready') # Current path self._path = QtCore.QDir.currentPath() # Load settings from ini file self.load_config() # Load any selected files for filename in filenames: self.load_file(filename)
def create_menu(self): """ Creates this widget's menu. """ self._menu = self.menuBar() # File menu self._menu_file = self._menu.addMenu('&File') # File > Open self._tool_open = QtWidgets.QAction('&Open', self) self._tool_open.setShortcut('Ctrl+O') self._tool_open.setStatusTip('Open a file') self._tool_open.setIcon(QtGui.QIcon.fromTheme('document-open')) self._tool_open.triggered.connect(self.action_open) self._menu_file.addAction(self._tool_open) # File > ---- self._menu_file.addSeparator() # File > Quit self._tool_exit = QtWidgets.QAction('&Quit', self) self._tool_exit.setShortcut('Ctrl+Q') self._tool_exit.setStatusTip('Exit application.') self._tool_exit.setIcon(QtGui.QIcon.fromTheme('application-exit')) self._tool_exit.triggered.connect(self.close) self._menu_file.addAction(self._tool_exit) # Help menu self._menu_help = self._menu.addMenu('&Help') # Help > About self._tool_about = QtWidgets.QAction('&About', self) self._tool_about.setStatusTip('View information about this program.') self._tool_about.triggered.connect(self.action_about) self._menu_help.addAction(self._tool_about) # Help > License self._tool_license = QtWidgets.QAction('&License', self) self._tool_license.setStatusTip('View this program\'s license info.') self._tool_license.triggered.connect(self.action_license) self._menu_help.addAction(self._tool_license)
def create_info_tab(self): """ Creates a tab displaying information about the file. """ widget = QtWidgets.QTextEdit(self) widget.setText(self._atf.info()) widget.setReadOnly(True) return widget
def create_graph_tab(self, key, data): """ Creates a widget displaying the ``data`` stored under ``key``. """ widget = QtWidgets.QWidget(self) # Create figure figure = matplotlib.figure.Figure() figure.suptitle(self._filename) canvas = backend.FigureCanvasQTAgg(figure) canvas.setParent(widget) axes = figure.add_subplot(1, 1, 1) axes.set_title(key) toolbar = backend.NavigationToolbar2QT(canvas, widget) # Draw lines axes.plot(self._time, data) # Create a layout vbox = QtWidgets.QVBoxLayout() vbox.addWidget(canvas) vbox.addWidget(toolbar) widget.setLayout(vbox) self._figures.append(figure) self._axes.append(axes) return widget
def __init__(self, parent, sim_method, output_stream, duration=1000): super(Explorer, self).__init__(parent) self.setWindowTitle('Myokit Explorer') self._sim_method = sim_method self._stream = output_stream # Set guess for run times guess_pre = 0 guess_run = duration # Explorer data self._data = None self._keys = None # Fix background color of line edits self.setStyleSheet('QLineEdit{background: white;}') # Create top widgets label1 = QtWidgets.QLabel('Run unlogged for ') label2 = QtWidgets.QLabel(' and then log for ') self._pre_field = QtWidgets.QLineEdit(str(guess_pre)) self._pre_valid = QtGui.QDoubleValidator() self._pre_valid.setBottom(0) self._pre_field.setValidator(self._pre_valid) self._run_field = QtWidgets.QLineEdit(str(guess_run)) self._run_valid = QtGui.QDoubleValidator() self._run_valid.setBottom(0) self._run_field.setValidator(self._run_valid) self._clear_button = QtWidgets.QPushButton('Clear graphs') self._clear_button.clicked.connect(self.action_clear) self._run_button = QtWidgets.QPushButton('Run') self._run_button.clicked.connect(self.action_run) # Create graph widgets self._axes = None self._figure = matplotlib.figure.Figure() self._canvas = backend.FigureCanvasQTAgg(self._figure) self._toolbar = backend.NavigationToolbar2QT(self._canvas, self) self._select_x = QtWidgets.QComboBox() self._select_x.currentIndexChanged.connect(self.combo_changed) self._select_y = QtWidgets.QComboBox() self._select_y.currentIndexChanged.connect(self.combo_changed) # Create bottom widgets self._close_button = QtWidgets.QPushButton('Close') self._close_button.clicked.connect(self.action_close) # Create button layout button_layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.LeftToRight) button_layout.addWidget(label1) button_layout.addWidget(self._pre_field) button_layout.addWidget(label2) button_layout.addWidget(self._run_field) button_layout.addWidget(self._clear_button) button_layout.addWidget(self._run_button) # Create graph options layout graph_option_layout = QtWidgets.QBoxLayout( QtWidgets.QBoxLayout.LeftToRight) graph_option_layout.addWidget(self._select_x) graph_option_layout.addWidget(self._select_y) # Create bottom layout bottom_layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.LeftToRight) bottom_layout.addWidget(self._close_button) # Create central layout layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) layout.addLayout(button_layout) layout.addLayout(graph_option_layout) layout.addWidget(self._canvas) layout.addWidget(self._toolbar) layout.addLayout(bottom_layout) self.setLayout(layout)
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, editor): # New style doesn't work: QtWidgets.QDialog.__init__(self, editor, Qt.Window) self.setWindowTitle('Find and replace') self._editor = editor # Fix background color of line edits self.setStyleSheet('QLineEdit{background: white;}') # Create widgets self._close_button = QtWidgets.QPushButton('Close') self._close_button.clicked.connect(self.action_close) self._replace_all_button = QtWidgets.QPushButton('Replace all') self._replace_all_button.clicked.connect(self.action_replace_all) self._replace_button = QtWidgets.QPushButton('Replace') self._replace_button.clicked.connect(self.action_replace) self._find_button = QtWidgets.QPushButton('Find') self._find_button.clicked.connect(self.action_find) self._search_label = QtWidgets.QLabel('Search for') self._search_field = QtWidgets.QLineEdit() self._replace_label = QtWidgets.QLabel('Replace with') self._replace_field = QtWidgets.QLineEdit() self._case_check = QtWidgets.QCheckBox('Case sensitive') self._whole_check = QtWidgets.QCheckBox('Match whole word only') # Create layout text_layout = QtWidgets.QGridLayout() text_layout.addWidget(self._search_label, 0, 0) text_layout.addWidget(self._search_field, 0, 1) text_layout.addWidget(self._replace_label, 1, 0) text_layout.addWidget(self._replace_field, 1, 1) check_layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) check_layout.addWidget(self._case_check) check_layout.addWidget(self._whole_check) button_layout = QtWidgets.QGridLayout() button_layout.addWidget(self._close_button, 0, 0) button_layout.addWidget(self._replace_all_button, 0, 1) button_layout.addWidget(self._replace_button, 0, 2) button_layout.addWidget(self._find_button, 0, 3) layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) layout.addLayout(text_layout) layout.addLayout(check_layout) layout.addLayout(button_layout) self.setLayout(layout) self._search_field.setEnabled(True) self._replace_field.setEnabled(True)
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)
def load_data_file(self, fname): """ Attempts to load the given data block 2d file. """ self._timer.stop() # Fix path fname = os.path.abspath(str(fname)) self._path = os.path.dirname(fname) # Try loading file. self.statusBar().showMessage('Loading ' + str(fname)) n = 1000000 pd = QtWidgets.QProgressDialog('Loading data file...', 'Cancel', 0, n) pd.setWindowModality(Qt.WindowModal) pd.setValue(0) class Reporter(myokit.ProgressReporter): def __init__(self, pd): self._pd = pd def enter(self, msg=None): pass def exit(self): pass def update(self, f): self._pd.setValue((int)(n * f)) return not self._pd.wasCanceled() reporter = Reporter(pd) try: data = myokit.DataBlock2d.load(fname, progress=reporter) del (reporter) except myokit.DataBlockReadError: pd.reset() self.statusBar().showMessage('Load failed.') QtWidgets.QMessageBox.warning( self, TITLE, '<h1>Unable to read file.</h1>' '<p>The given filename <code>' + str(fname) + '</code>' ' could not be read as a <code>myokit.DataBlock2d</code>.</p>') return except Exception as e: pd.reset() self.statusBar().showMessage('Load failed.') self.display_exception() return finally: if pd.wasCanceled(): self.statusBar().showMessage('Load canceled.') return # Don't load empty files if data.len2d() < 1: self.statusBar().showMessage('Load failed: empty file.') QtWidgets.QMessageBox.warning( self, TITLE, '<h1>Unable to read file.</h1>' '<p>The given filename <code>' + str(fname) + '</code>' ' does not contain any 2d data.</p>') return # File loaded okay self.statusBar().showMessage('File loaded succesfully.') self._file = fname self._data = data self.update_window_title() # Update recent file list try: # Remove fname from recent files list i = self._recent_files.index(fname) self._recent_files = self._recent_files[:i] \ + self._recent_files[i+1:] except ValueError: pass self._recent_files.insert(0, fname) self._recent_files = self._recent_files[:N_RECENT_FILES] self.update_recent_files_menu() # Update video scene nt, ny, nx = self._data.shape() self._colormap_size = max(int(0.05 * nx), 1) self._video_scene.clear() self._video_scene.resize(nx, ny, 2 * self._colormap_size) self._video_view.resizeEvent() self._video_iframe = 0 # Add empty video item to video scene self._video_pixmap = QtGui.QPixmap(nx, ny) self._video_item = QtWidgets.QGraphicsPixmapItem(self._video_pixmap) self._video_scene.addItem(self._video_item) # Add empty colormap item to video scene self._colormap_pixmap = QtGui.QPixmap(self._colormap_size, ny) self._colormap_item = QtWidgets.QGraphicsPixmapItem( self._colormap_pixmap) self._colormap_item.setPos(nx + self._colormap_size, 0) self._video_scene.addItem(self._colormap_item) # Move slider to correct position self._slider.setMaximum(nt) self._slider.setPageStep(int(nt / 20)) # Update controls for i in range(self._variable_select.count(), 0, -1): self._variable_select.removeItem(i - 1) variable = None for name in data.keys2d(): self._variable_select.addItem(name) if variable is None or name in ('membrane.V', 'membrane.v'): variable = name self.action_set_variable(variable) self.action_set_colormap(self._colormap) # Update graph area self._graph_area.set_data(self._data)
def create_menu(self): """ Creates this widget's menu. """ self._menu = self.menuBar() # File menu self._menu_file = self._menu.addMenu('&File') # File > Open self._tool_open = QtWidgets.QAction('&Open', self) self._tool_open.setShortcut('Ctrl+O') self._tool_open.setStatusTip('Open a DataLog for inspection.') self._tool_open.setIcon(QtGui.QIcon.fromTheme('document-open')) self._tool_open.triggered.connect(self.action_open) self._menu_file.addAction(self._tool_open) # File > ---- self._menu_file.addSeparator() # File > Recent files self._recent_file_tools = [] for i in xrange(N_RECENT_FILES): tool = QtWidgets.QAction(self, visible=False) tool.triggered.connect(self.action_recent_file) self._recent_file_tools.append(tool) self._menu_file.addAction(tool) # File > ---- self._menu_file.addSeparator() # File > Quit self._tool_exit = QtWidgets.QAction('&Quit', self) self._tool_exit.setShortcut('Ctrl+Q') self._tool_exit.setStatusTip('Exit application.') self._tool_exit.setIcon(QtGui.QIcon.fromTheme('application-exit')) self._tool_exit.triggered.connect(self.close) self._menu_file.addAction(self._tool_exit) # Data menu self._menu_data = self._menu.addMenu('&Data') # Data > Extract frame self._tool_exframe = QtWidgets.QAction('Extract &frame', self) self._tool_exframe.setStatusTip('Extract the current frame as csv' ' file.') self._tool_exframe.triggered.connect(self.action_extract_frame) self._menu_data.addAction(self._tool_exframe) # Data > Extract graphs self._tool_exgraph = QtWidgets.QAction('Extract &graphs', self) self._tool_exgraph.setStatusTip('Extract the current graphs.') self._tool_exgraph.triggered.connect(self.action_extract_graphs) self._menu_data.addAction(self._tool_exgraph) # Data > ---- self._menu_data.addSeparator() # Data > Extract frame as image self._tool_imgframe = QtWidgets.QAction('Save frame as &image', self) self._tool_imgframe.setStatusTip('Save the current frame as an image' ' file.') self._tool_imgframe.triggered.connect(self.action_extract_frame_image) self._menu_data.addAction(self._tool_imgframe) # Data > Extract colormap as image self._tool_imgcolor = QtWidgets.QAction('Save &colormap as image', self) self._tool_imgcolor.setStatusTip('Save the colormap as an image file.') self._tool_imgcolor.triggered.connect( self.action_extract_colormap_image) self._menu_data.addAction(self._tool_imgcolor) # Help menu self._menu_help = self._menu.addMenu('&Help') # Help > About self._tool_about = QtWidgets.QAction('&About', self) self._tool_about.setStatusTip('View information about this program.') self._tool_about.triggered.connect(self.action_about) self._menu_help.addAction(self._tool_about) self._tool_license = QtWidgets.QAction('&License', self) self._tool_license.setStatusTip('View this program\'s license info.') self._tool_license.triggered.connect(self.action_license) self._menu_help.addAction(self._tool_license)
def __init__(self, parent, editor): super(FindReplaceWidget, self).__init__(parent) self._editor = editor # Create widgets self._replace_all_button = QtWidgets.QPushButton('Replace all') self._replace_all_button.clicked.connect(self.action_replace_all) self._replace_button = QtWidgets.QPushButton('Replace') self._replace_button.clicked.connect(self.action_replace) self._find_button = QtWidgets.QPushButton('Find') self._find_button.clicked.connect(self.action_find) self._search_label = QtWidgets.QLabel('Search for') self._search_field = QtWidgets.QLineEdit() self._replace_label = QtWidgets.QLabel('Replace with') self._replace_field = QtWidgets.QLineEdit() self._case_check = QtWidgets.QCheckBox('Case sensitive') self._whole_check = QtWidgets.QCheckBox('Match whole word only') # Create layout text_layout = QtWidgets.QGridLayout() text_layout.addWidget(self._search_label, 0, 0) text_layout.addWidget(self._search_field, 0, 1) text_layout.addWidget(self._replace_label, 1, 0) text_layout.addWidget(self._replace_field, 1, 1) check_layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) check_layout.addWidget(self._case_check) check_layout.addWidget(self._whole_check) button_layout = QtWidgets.QGridLayout() button_layout.addWidget(self._replace_all_button, 0, 1) button_layout.addWidget(self._replace_button, 0, 2) button_layout.addWidget(self._find_button, 0, 3) layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) layout.addLayout(text_layout) layout.addLayout(check_layout) layout.addLayout(button_layout) layout.addStretch(1) self.setLayout(layout) # Accept keyboard focus on search and replace fields self._search_field.setEnabled(True) self._replace_field.setEnabled(True)