def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.pages_widget.setMinimumWidth(600) self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.ok_btn = bbox.button(QDialogButtonBox.Ok) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) self.contents_widget.setMinimumWidth(220) self.contents_widget.setMinimumHeight(400) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setStretchFactor(0, 1) hsplitter.setStretchFactor(1, 2) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots if self.main: self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, ert: EnKFMain, notifier: ErtNotifier, config_file: str): self.notifier = notifier QWidget.__init__(self) self.ert = ert self.facade = LibresFacade(ert) self._config_file = config_file self.setObjectName("Simulation_panel") layout = QVBoxLayout() self._simulation_mode_combo = QComboBox() self._simulation_mode_combo.setObjectName("Simulation_mode") addHelpToWidget(self._simulation_mode_combo, "run/simulation_mode") self._simulation_mode_combo.currentIndexChanged.connect( self.toggleSimulationMode) simulation_mode_layout = QHBoxLayout() simulation_mode_layout.addSpacing(10) simulation_mode_layout.addWidget(QLabel("Simulation mode:"), 0, Qt.AlignVCenter) simulation_mode_layout.addWidget(self._simulation_mode_combo, 0, Qt.AlignVCenter) simulation_mode_layout.addSpacing(20) self.run_button = QToolButton() self.run_button.setObjectName("start_simulation") self.run_button.setText("Start simulation") self.run_button.setIcon(resourceIcon("play_circle.svg")) self.run_button.setIconSize(QSize(32, 32)) self.run_button.clicked.connect(self.runSimulation) self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) addHelpToWidget(self.run_button, "run/start_simulation") simulation_mode_layout.addWidget(self.run_button) simulation_mode_layout.addStretch(1) layout.addSpacing(5) layout.addLayout(simulation_mode_layout) layout.addSpacing(10) self._simulation_stack = QStackedWidget() self._simulation_stack.setLineWidth(1) self._simulation_stack.setFrameStyle(QFrame.StyledPanel) layout.addWidget(self._simulation_stack) self._simulation_widgets = OrderedDict() """ :type: OrderedDict[BaseRunModel,SimulationConfigPanel]""" self.addSimulationConfigPanel(SingleTestRunPanel(ert, notifier)) self.addSimulationConfigPanel(EnsembleExperimentPanel(ert, notifier)) if self.facade.have_observations: self.addSimulationConfigPanel(EnsembleSmootherPanel(ert, notifier)) self.addSimulationConfigPanel( MultipleDataAssimilationPanel(self.facade, notifier)) self.addSimulationConfigPanel( IteratedEnsembleSmootherPanel(self.facade, notifier)) self.setLayout(layout)
def setup(self, fname): """Setup Run Configuration dialog with filename *fname*""" combo_label = QLabel(_("Select a run configuration:")) self.combo = QComboBox() self.combo.setMaxVisibleItems(20) self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.stack = QStackedWidget() configurations = _get_run_configurations() for index, (filename, options) in enumerate(configurations): if fname == filename: break else: # There is no run configuration for script *fname*: # creating a temporary configuration that will be kept only if # dialog changes are accepted by the user configurations.insert(0, (fname, RunConfiguration(fname).get())) index = 0 for filename, options in configurations: widget = RunConfigOptions(self) widget.set(options) self.combo.addItem(filename) self.stack.addWidget(widget) self.combo.currentIndexChanged.connect(self.stack.setCurrentIndex) self.combo.setCurrentIndex(index) self.add_widgets(combo_label, self.combo, 10, self.stack) self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self.setWindowTitle(_("Run configuration per file"))
class FormComboWidget(QWidget): update_buttons = Signal() def __init__(self, datalist, comment="", parent=None): QWidget.__init__(self, parent) layout = QVBoxLayout() self.setLayout(layout) self.combobox = QComboBox() layout.addWidget(self.combobox) self.stackwidget = QStackedWidget(self) layout.addWidget(self.stackwidget) self.combobox.currentIndexChanged.connect( self.stackwidget.setCurrentIndex) self.widgetlist = [] for data, title, comment in datalist: self.combobox.addItem(title) widget = FormWidget(data, comment=comment, parent=self) self.stackwidget.addWidget(widget) self.widgetlist.append(widget) def setup(self): for widget in self.widgetlist: widget.setup() def get(self): return [ widget.get() for widget in self.widgetlist]
def __init__(self): super(ConfigDialog, self).__init__() self.needs_reload = True # Set size and position self.setGeometry(0, 0, 900, 550) frameGm = self.frameGeometry() screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos()) centerPoint = QApplication.desktop().screenGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) self.contentsWidget = QListView() self.contentsWidget.setViewMode(QListView.IconMode) # self.contentsWidget.setIconSize(QSize(96, 84)) self.contentsWidget.setMovement(QListView.Static) self.contentsWidget.setMaximumWidth(174) self.contentsWidget.setSpacing(12) self.contentsWidget.setSelectionMode(QAbstractItemView.SingleSelection) self.contentsModel = QStandardItemModel() self.contentsWidget.setModel(self.contentsModel) self.contentsWidget.selectionModel().currentChanged.connect( self.changePage) self.buttonboxWidget = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Apply # | QDialogButtonBox.Help ) self.buttonboxWidget.button(QDialogButtonBox.Ok).clicked.connect( self.ok) self.buttonboxWidget.button(QDialogButtonBox.Apply).clicked.connect( self.apply) self.buttonboxWidget.button(QDialogButtonBox.Cancel).clicked.connect( self.close) self.pagesWidget = QStackedWidget() horizontalLayout = QHBoxLayout() horizontalLayout.addWidget(self.contentsWidget) horizontalLayout.addWidget(self.pagesWidget, 1) mainLayout = QVBoxLayout() mainLayout.addLayout(horizontalLayout) # mainLayout.addStretch(1) mainLayout.addSpacing(12) mainLayout.addWidget(self.buttonboxWidget) self.setLayout(mainLayout) self.setWindowTitle("Config Dialog") # Set modality self.setModal(True) self.lastwidget = None # Restore Settings pluginmanager.attach(self.request_reload, Filters.COMPLETE)
def __init__(self, parent=None): from ...settings import get_settings super().__init__(parent) self.setWindowTitle(trans._("Preferences")) self._settings = get_settings() self._stack = QStackedWidget(self) self._list = QListWidget(self) self._list.setObjectName("Preferences") self._list.currentRowChanged.connect(self._stack.setCurrentIndex) # Set up buttons self._button_cancel = QPushButton(trans._("Cancel")) self._button_cancel.clicked.connect(self.reject) self._button_ok = QPushButton(trans._("OK")) self._button_ok.clicked.connect(self.accept) self._button_ok.setDefault(True) self._button_restore = QPushButton(trans._("Restore defaults")) self._button_restore.clicked.connect(self._restore_default_dialog) # Layout left_layout = QVBoxLayout() left_layout.addWidget(self._list) left_layout.addStretch() left_layout.addWidget(self._button_restore) left_layout.addWidget(self._button_cancel) left_layout.addWidget(self._button_ok) self.setLayout(QHBoxLayout()) self.layout().addLayout(left_layout, 1) self.layout().addWidget(self._stack, 3) # Build dialog from settings self._rebuild_dialog()
def __init__(self, image: Image, transform_dict: Dict[str, TransformBase] = None): super().__init__() if transform_dict is None: transform_dict = image_transform_dict self.choose = QComboBox() self.stacked = QStackedWidget() for key, val in transform_dict.items(): self.choose.addItem(key) initial_values = val.calculate_initial(image) form_widget = FormWidget( val.get_fields_per_dimension(image.get_dimension_letters()), initial_values) self.stacked.addWidget(form_widget) self.choose.currentIndexChanged.connect(self.stacked.setCurrentIndex) self.cancel_btn = QPushButton("Cancel") self.cancel_btn.clicked.connect(self.reject) self.process_btn = QPushButton("Process") self.process_btn.clicked.connect(self.process) self.transform_dict = transform_dict self.result_val: ImageAdjustTuple = None layout = QGridLayout() layout.addWidget(self.choose, 0, 0, 1, 3) layout.addWidget(self.stacked, 1, 0, 1, 3) layout.addWidget(self.cancel_btn, 2, 0) layout.addWidget(self.process_btn, 2, 2) self.setLayout(layout)
class FormComboWidget(QWidget): update_buttons = Signal() def __init__(self, datalist, comment="", parent=None): QWidget.__init__(self, parent) layout = QVBoxLayout() self.setLayout(layout) self.combobox = QComboBox() layout.addWidget(self.combobox) self.stackwidget = QStackedWidget(self) layout.addWidget(self.stackwidget) self.combobox.currentIndexChanged.connect( self.stackwidget.setCurrentIndex) self.widgetlist = [] for data, title, comment in datalist: self.combobox.addItem(title) widget = FormWidget(data, comment=comment, parent=self) self.stackwidget.addWidget(widget) self.widgetlist.append(widget) def setup(self): for widget in self.widgetlist: widget.setup() def get(self): return [widget.get() for widget in self.widgetlist]
class RunConfigDialog(BaseRunConfigDialog): """Run configuration dialog box: multiple file version""" def __init__(self, parent=None): BaseRunConfigDialog.__init__(self, parent) self.file_to_run = None self.combo = None self.stack = None def run_btn_clicked(self): """Run button was just clicked""" self.file_to_run = to_text_string(self.combo.currentText()) def setup(self, fname): """Setup Run Configuration dialog with filename *fname*""" combo_label = QLabel(_("Select a run configuration:")) self.combo = QComboBox() self.combo.setMaxVisibleItems(20) self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.stack = QStackedWidget() configurations = _get_run_configurations() for index, (filename, options) in enumerate(configurations): if fname == filename: break else: # There is no run configuration for script *fname*: # creating a temporary configuration that will be kept only if # dialog changes are accepted by the user configurations.insert(0, (fname, RunConfiguration(fname).get())) index = 0 for filename, options in configurations: widget = RunConfigOptions(self) widget.set(options) self.combo.addItem(filename) self.stack.addWidget(widget) self.combo.currentIndexChanged.connect(self.stack.setCurrentIndex) self.combo.setCurrentIndex(index) self.add_widgets(combo_label, self.combo, 10, self.stack) self.add_button_box(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self.setWindowTitle(_("Run configuration per file")) def accept(self): """Reimplement Qt method""" configurations = [] for index in range(self.stack.count()): filename = to_text_string(self.combo.itemText(index)) runconfigoptions = self.stack.widget(index) if index == self.stack.currentIndex() and\ not runconfigoptions.is_valid(): return options = runconfigoptions.get() configurations.append( (filename, options) ) _set_run_configurations(configurations) QDialog.accept(self)
def __init__(self, config_file): QWidget.__init__(self) self._config_file = config_file self._ee_config = None if FeatureToggling.is_enabled("ensemble-evaluator"): self._ee_config = EvaluatorServerConfig() self.setObjectName("Simulation_panel") layout = QVBoxLayout() self._simulation_mode_combo = QComboBox() self._simulation_mode_combo.setObjectName("Simulation_mode") addHelpToWidget(self._simulation_mode_combo, "run/simulation_mode") self._simulation_mode_combo.currentIndexChanged.connect( self.toggleSimulationMode) simulation_mode_layout = QHBoxLayout() simulation_mode_layout.addSpacing(10) simulation_mode_layout.addWidget(QLabel("Simulation mode:"), 0, Qt.AlignVCenter) simulation_mode_layout.addWidget(self._simulation_mode_combo, 0, Qt.AlignVCenter) simulation_mode_layout.addSpacing(20) self.run_button = QToolButton() self.run_button.setObjectName("start_simulation") self.run_button.setIconSize(QSize(32, 32)) self.run_button.setText("Start Simulation") self.run_button.setIcon(resourceIcon("ide/gear_in_play")) self.run_button.clicked.connect(self.runSimulation) self.run_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) addHelpToWidget(self.run_button, "run/start_simulation") simulation_mode_layout.addWidget(self.run_button) simulation_mode_layout.addStretch(1) layout.addSpacing(5) layout.addLayout(simulation_mode_layout) layout.addSpacing(10) self._simulation_stack = QStackedWidget() self._simulation_stack.setLineWidth(1) self._simulation_stack.setFrameStyle(QFrame.StyledPanel) layout.addWidget(self._simulation_stack) self._simulation_widgets = OrderedDict() """ :type: OrderedDict[BaseRunModel,SimulationConfigPanel]""" self.addSimulationConfigPanel(SingleTestRunPanel()) self.addSimulationConfigPanel(EnsembleExperimentPanel()) if ERT.ert.have_observations(): self.addSimulationConfigPanel(EnsembleSmootherPanel()) self.addSimulationConfigPanel(MultipleDataAssimilationPanel()) self.addSimulationConfigPanel(IteratedEnsembleSmootherPanel()) self.setLayout(layout)
def __init__(self, parent=None, objname=None): QDialog.__init__(self, parent) # If used for data object in tree, the main is the tree widget. self.parent = parent self.objname = objname # Widgets self.pages_widget = QStackedWidget() self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Ezcad), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) if self.objname is None: self.setWindowTitle(_('Preferences')) else: self.setWindowTitle(_('Preferences of ') + self.objname) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setSizes([150,500]) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on ezcad first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, parent=None, model=None): super(StackedCanvasView, self).__init__(parent) if model is not None: self.setModel(model) self.canvas_display_widgets = [ CanvasDisplayTabWidget(), SplitHorizontal(), SplitVertical(), SplitThreeView(), SplitGridView() ] ### Create stacked widget and fill pages with different canvas display widgets self.stackedwidget = QStackedWidget(self) # Create a visual layout section for the buttons that are used to switch the widgets self.buttonpanel = QHBoxLayout() self.buttonpanel.addStretch(10) # Create a logical button grouping that will: # - show the currently selected view (button will be checked/pressed) # - allow for switching the buttons/views in a mutually exclusive manner (only one can be pressed at a time) self.buttongroup = QButtonGroup() def add_canvas_display_widgets(): for i in range(len(self.canvas_display_widgets)): # Add the view to the stacked widget self.stackedwidget.addWidget(self.canvas_display_widgets[i]) # Create a button, using the view's recommended display icon button = QPushButton(self) button.setCheckable(True) button.setIcon(self.canvas_display_widgets[i].icon) button.setToolTip( getattr(self.canvas_display_widgets[i], "tool_tip", None)) button.setWhatsThis( getattr(self.canvas_display_widgets[i], "whats_this", None)) # Add the button to the logical button group self.buttongroup.addButton(button, i) # Add the button to the visual layout section self.buttonpanel.addWidget(button) add_canvas_display_widgets() def set_default_canvas_display_widget(): # The first button added to the buttongroup will be the currently selected button (and therefore view) self.buttongroup.button(0).setChecked(True) set_default_canvas_display_widget() # Whenever a button is switched, capture its id (corresponds to integer index in our case); # this will handle switching the view and displaying canvases. self.buttongroup.idToggled.connect(self.switch_view) # define outer layout & add stacked widget and button panel self.layout = QVBoxLayout() self.layout.addWidget(self.stackedwidget) self.layout.addLayout(self.buttonpanel) self.setLayout(self.layout)
def __init__(self, *args, **kwargs): # define status images self.status_icons = { -2: QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'depth_status_delay.png')), -1: QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'depth_status_in_use.png')), 1: QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'depth_status_done.png')), 0: QPixmap( os.path.join(os.path.dirname(__file__), 'icons', 'depth_status_off.png')), } # Settings self.subject_settings = None self.procedure_settings = None self.depth_settings = None self.features_settings = None # Plot options self.plot_config = {} self.y_range = uVRANGE self.plot_stack = QStackedWidget() # generate a dict {chan_label: {Feature:[stack idx, latest_datum]}} self.stack_dict = {} # shared memory to display the currently monitored electrode self.monitored_channel_mem = QSharedMemory() self.monitored_channel_mem.setKey("MonitoredChannelMemory") self.monitored_channel_mem.attach(QSharedMemory.ReadOnly) # wrap up init super(FeaturesPlotWidget, self).__init__(*args, **kwargs) self.move(WINDOWDIMS_FEATURES[0], WINDOWDIMS_FEATURES[1]) self.resize(WINDOWDIMS_FEATURES[2], WINDOWDIMS_FEATURES[3]) self.setMaximumWidth(WINDOWDIMS_FEATURES[2]) # initialize plots self.layout().addWidget(self.plot_stack) self.refresh_axes() # Extra time on purpose. # Define and start processes # will only start processes when settings are received self.depth_wrapper = ProcessWrapper('Depth_Process') self.depth_process_running = False self.features_wrapper = ProcessWrapper('Features_Process') self.features_process_running = False
def __init__(self): super(ExtendedTabWidget, self).__init__() self._tab_bar = None self._stack = QStackedWidget() self._main_layout = QBoxLayout(QBoxLayout.LeftToRight) self._main_layout.setContentsMargins(0, 0, 0, 0) self._main_layout.addWidget(self._stack) self.setLayout(self._main_layout)
def __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.stack.setStyleSheet("QStackedWidget{padding: 0px; border: 0px}") self.shellwidgets = {} # Layout layout = QGridLayout(self) layout.addWidget(self.stack)
class Editor(QDialog): """Basic scene editor.""" def __init__(self, parent: MainWindow, renderers: List[Renderer]) -> None: """Initialize the Editor.""" super().__init__(parent=parent) self.renderers = renderers self.tree_widget = QTreeWidget() self.tree_widget.setHeaderHidden(True) self.stacked_widget = QStackedWidget() self.layout = QHBoxLayout() self.layout.addWidget(self.tree_widget) self.layout.addWidget(self.stacked_widget) def _selection_callback() -> None: for item in self.tree_widget.selectedItems(): widget_idx = item.data(0, Qt.ItemDataRole.UserRole) self.stacked_widget.setCurrentIndex(widget_idx) self.tree_widget.itemSelectionChanged.connect(_selection_callback) self.setLayout(self.layout) self.setWindowTitle("Editor") self.setModal(True) self.update() def update(self) -> None: """Update the internal widget list.""" self.tree_widget.clear() for idx, renderer in enumerate(self.renderers): actors = renderer._actors # pylint: disable=protected-access widget_idx = self.stacked_widget.addWidget( _get_renderer_widget(renderer)) top_item = QTreeWidgetItem(self.tree_widget, ["Renderer {}".format(idx)]) top_item.setData(0, Qt.ItemDataRole.UserRole, widget_idx) self.tree_widget.addTopLevelItem(top_item) for name, actor in actors.items(): if actor is not None: widget_idx = self.stacked_widget.addWidget( _get_actor_widget(actor)) child_item = QTreeWidgetItem(top_item, [name]) child_item.setData(0, Qt.ItemDataRole.UserRole, widget_idx) top_item.addChild(child_item) self.tree_widget.expandAll() def toggle(self) -> None: """Toggle the editor visibility.""" self.update() if self.isVisible(): self.hide() else: self.show()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Widgets self._stack = QStackedWidget(self) self._shellwidgets = {} # Layout layout = QVBoxLayout() layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._stack) self.setLayout(layout)
def __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QGridLayout(self) layout.addWidget(self.stack) # Initialize plugin self.initialize_plugin()
def setupui(self): vbl = QVBoxLayout(self) self.stack = QStackedWidget(self) vbl.addWidget(self.stack) rbA = QRadioButton('Antennas', self) rbP = QRadioButton('Positions', self) rbA.toggled.connect(_part(self.toggle_button, 0)) rbP.toggled.connect(_part(self.toggle_button, 1)) self.radio_buttons.append(rbA) self.radio_buttons.append(rbP) rbA.setChecked(True) hbl = QHBoxLayout() hbl.addStretch() hbl.addWidget(rbA) hbl.addStretch() hbl.addWidget(rbP) hbl.addStretch() vbl.addItem(hbl) # ##### Antennas Widget ###### stack1 = QWidget(self.stack) self.stack.addWidget(stack1) vbl = QVBoxLayout(stack1) graph = self.create_graph(stack1, 'ant') vbl.addWidget(graph) stats = self.create_statistics(stack1, 'ant') vbl.addWidget(stats) # ##### Position and Amplitudes Widget ###### stack2 = QWidget(self.stack) self.stack.addWidget(stack2) vbl = QVBoxLayout(stack2) graph = self.create_graph(stack2, 'pos') vbl.addWidget(graph) graph = self.create_graph(stack2, 'amp') vbl.addWidget(graph) self.setStyleSheet(""" #SinglePassDataGraph{ min-width:48em; min-height:24em; } QLabel{ min-width:6em; max-width:6em; min-height:1.5em; max-height:1.5em; }""")
def __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.stack.setStyleSheet("QStackedWidget{padding: 0px; border: 0px}") self.shellwidgets = {} # Layout layout = QVBoxLayout() layout.addWidget(self.stack) self.setLayout(layout) # Initialize plugin self.initialize_plugin()
def __init__(self, parent): QWidget.__init__(self, parent) SpyderPluginMixin.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QVBoxLayout() layout.addWidget(self.stack) self.setLayout(layout) # Initialize plugin self.initialize_plugin()
def __init__( self, save_register: typing.Dict[str, type(SaveBase)], system_widget=True, base_values: typing.Optional[dict] = None, parent=None, history: typing.Optional[typing.List[str]] = None, file_mode=QFileDialog.AnyFile, ): super().__init__(parent) self.setFileMode(file_mode) self.save_register = { x.get_name_with_suffix(): x for x in save_register.values() } self.setOption(QFileDialog.DontUseNativeDialog, not system_widget) self.setAcceptMode(QFileDialog.AcceptSave) self.filterSelected.connect(self.change_filter) self.setNameFilters(self.save_register.keys()) self.accepted_native = False self.values = {} self.names = [] if history is not None: history = self.history() + history self.setHistory(history) self.base_values = base_values if base_values is not None else {} if not system_widget: widget = QStackedWidget() for name, val in self.save_register.items(): wi = FormWidget(val.get_fields()) if name in self.base_values: wi.set_values(self.base_values[name]) widget.addWidget(wi) self.names.append(name) self.filterSelected.connect(self.change_parameters) layout = self.layout() if isinstance(layout, QGridLayout): # print(layout.columnCount(), layout.rowCount()) # noinspection PyArgumentList layout.addWidget(widget, 0, layout.columnCount(), layout.rowCount(), 1) self.stack_widget = widget else: layout.addWidget(widget) self.stack_widget = widget self.selectNameFilter(self.names[0])
def _init_ui(self): # Widgets self._combobox = QComboBox() self._stack = QStackedWidget() # Layouts layout = ParameterWidget._init_ui(self) layout.addRow(self._combobox) layout.addRow(self._stack) # Register classes self._widget_indexes = {} for entry_point in iter_entry_points('pyhmsa_gui.spec.condition.calibration'): widget_class = entry_point.load(require=False) widget = widget_class() self._combobox.addItem(widget.accessibleName().title()) self._widget_indexes[widget.CLASS] = self._stack.addWidget(widget) widget.edited.connect(self.edited) # Signals self._combobox.currentIndexChanged.connect(self._on_combo_box) self._combobox.currentIndexChanged.connect(self.edited) return layout
def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.pages_widget.setMinimumWidth(600) self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) self.contents_widget.setMinimumWidth(220) self.contents_widget.setMinimumHeight(400) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setStretchFactor(0, 1) hsplitter.setStretchFactor(1, 2) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots if self.main: self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, parent): self.main = parent # Spyder3 # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Fallback widget when no MxConsole available. # Spyder 4 output internal error message without this. self.blankwidget = QLabel(text="No MxConsole Available") self.blankwidget.setAlignment(Qt.AlignCenter) self.stack.addWidget(self.blankwidget) # On active tab in IPython console change self.main.ipyconsole.tabwidget.currentChanged.connect( self.on_ipyconsole_current_changed)
def __init__(self, datalist, comment="", parent=None): QWidget.__init__(self, parent) layout = QVBoxLayout() self.setLayout(layout) self.combobox = QComboBox() layout.addWidget(self.combobox) self.stackwidget = QStackedWidget(self) layout.addWidget(self.stackwidget) self.combobox.currentIndexChanged.connect( self.stackwidget.setCurrentIndex) self.widgetlist = [] for data, title, comment in datalist: self.combobox.addItem(title) widget = FormWidget(data, comment=comment, parent=self) self.stackwidget.addWidget(widget) self.widgetlist.append(widget)
def __init__(self, parent=None): super().__init__(parent) self._list = QListWidget(self) self._stack = QStackedWidget(self) self._list.setObjectName("Preferences") # Set up buttons self._button_cancel = QPushButton(trans._("Cancel")) self._button_ok = QPushButton(trans._("OK")) self._default_restore = QPushButton(trans._("Restore defaults")) # Setup self.setWindowTitle(trans._("Preferences")) self._button_ok.setDefault(True) # Layout left_layout = QVBoxLayout() left_layout.addWidget(self._list) left_layout.addStretch() left_layout.addWidget(self._default_restore) left_layout.addWidget(self._button_cancel) left_layout.addWidget(self._button_ok) main_layout = QHBoxLayout() main_layout.addLayout(left_layout, 1) main_layout.addWidget(self._stack, 3) self.setLayout(main_layout) # Signals self._list.currentRowChanged.connect( lambda index: self._stack.setCurrentIndex(index)) self._button_cancel.clicked.connect(self.on_click_cancel) self._button_ok.clicked.connect(self.on_click_ok) self._default_restore.clicked.connect(self.restore_defaults) self.rejected.connect(self.on_click_cancel) # Make widget self.make_dialog() self._list.setCurrentRow(0)
def __init__(self, parent=None): super().__init__(parent) self.contentsWidget = QListWidget() self.pagesWidget = QStackedWidget() self.plotPref = PlotPreferences(parent) self.dataPref = DataPreferences(parent) self.pagesWidget.addWidget(self.plotPref) self.pagesWidget.addWidget(self.dataPref) self.contentsWidget.addItem("Plot") self.contentsWidget.addItem("Data") self.contentsWidget.currentItemChanged.connect(self.changePage) self.contentsWidget.setCurrentRow(0) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Close) okButton = self.buttonBox.button(QDialogButtonBox.Ok) okButton.clicked.connect(self.ok) applyButton = self.buttonBox.button(QDialogButtonBox.Apply) applyButton.clicked.connect(self.apply) closeButton = self.buttonBox.button(QDialogButtonBox.Close) closeButton.clicked.connect(self.close) horizontalLayout = QHBoxLayout() horizontalLayout.addWidget(self.contentsWidget) horizontalLayout.addWidget(self.pagesWidget) self.contentsWidget.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContents) mainLayout = QVBoxLayout() mainLayout.addLayout(horizontalLayout) mainLayout.addWidget(self.buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Preferences")
def __init__(self, parent=None): self._parent = parent super().__init__(parent) self.oneDViewer = None self.strainSliceViewer = None self.vtk3dviewer = None self.plot_1d = QStackedWidget() self.plot_2d = QStackedWidget() self.plot_3d = QStackedWidget() self.message = QLabel("Load project files") self.message.setAlignment(Qt.AlignCenter) font = self.message.font() font.setPointSize(20) self.message.setFont(font) self.message2 = QLabel("Load project files") self.message2.setAlignment(Qt.AlignCenter) self.message2.setFont(font) self.plot_2d.addWidget(self.message) self.plot_3d.addWidget(self.message2) self.addTab(self.plot_1d, "1D") self.addTab(self.plot_2d, "2D") self.addTab(self.plot_3d, "3D") self.set_1d_mode(False) self.setCornerWidget(QLabel("Visualization Pane "), corner=Qt.TopLeftCorner)
def setup(self, fname): """Setup Run Configuration dialog with filename *fname*""" combo_label = QLabel(_("Select a run configuration:")) self.combo = QComboBox() self.combo.setMaxVisibleItems(20) self.stack = QStackedWidget() configurations = _get_run_configurations() for index, (filename, options) in enumerate(configurations): if fname == filename: break else: # There is no run configuration for script *fname*: # creating a temporary configuration that will be kept only if # dialog changes are accepted by the user configurations.insert(0, (fname, RunConfiguration(fname).get())) index = 0 for filename, options in configurations: widget = RunConfigOptions(self) widget.set(options) widget.layout().setContentsMargins(0, 0, 0, 0) self.combo.addItem(filename) self.stack.addWidget(widget) self.combo.currentIndexChanged.connect(self.stack.setCurrentIndex) self.combo.setCurrentIndex(index) layout = self.add_widgets(combo_label, self.combo, 10, self.stack) widget_dialog = QWidget() widget_dialog.setLayout(layout) scrollarea = QScrollArea(self) scrollarea.setWidget(widget_dialog) scrollarea.setMinimumWidth(600) scrollarea.setWidgetResizable(True) scroll_layout = QVBoxLayout(self) scroll_layout.addWidget(scrollarea) self.add_button_box(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.setWindowTitle(_("Run configuration per file"))
def _load_core_widget(self): setting = self.params["setting"] hlayout = QHBoxLayout() list_widget = QListWidget() stacked_widget = QStackedWidget() for key in setting.keys(): list_widget.addItem(key) widget = QWidget() widget_layout = QVBoxLayout() for value in setting[key]: self._create_form(widget_layout, [value]) widget_layout.addStretch() widget.setLayout(widget_layout) stacked_widget.addWidget(widget) hlayout.addWidget(list_widget) hlayout.addWidget(stacked_widget) hlayout.setStretch(0, 1) hlayout.setStretch(1, 5) list_widget.currentRowChanged.connect(stacked_widget.setCurrentIndex) list_widget.setCurrentRow(0) return hlayout
def __init__(self, parent: MainWindow, renderers: List[Renderer]) -> None: """Initialize the Editor.""" super().__init__(parent=parent) self.renderers = renderers self.tree_widget = QTreeWidget() self.tree_widget.setHeaderHidden(True) self.stacked_widget = QStackedWidget() self.layout = QHBoxLayout() self.layout.addWidget(self.tree_widget) self.layout.addWidget(self.stacked_widget) def _selection_callback() -> None: for item in self.tree_widget.selectedItems(): widget_idx = item.data(0, Qt.ItemDataRole.UserRole) self.stacked_widget.setCurrentIndex(widget_idx) self.tree_widget.itemSelectionChanged.connect(_selection_callback) self.setLayout(self.layout) self.setWindowTitle("Editor") self.setModal(True) self.update()
def __init__(self): runengine.initialize() deviceviewcontainer = DeviceView() devicelist = deviceviewcontainer.view controlsstack = QStackedWidget() devicelist.sigShowControl.connect(controlsstack.addSetWidget) self.stages = { 'Controls': GUILayout( controlsstack, left=devicelist, ), 'Plans': GUILayout(scripteditor(), left=devicelist), 'Run Engine': GUILayout(RunEngineWidget(), left=devicelist) } super(AcquirePlugin, self).__init__()
class ArrayEditor(QDialog): """Array Editor Dialog""" def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.data = None self.arraywidget = None self.stack = None self.layout = None # Values for 3d array editor self.dim_indexes = [{}, {}, {}] self.last_dim = 0 # Adjust this for changing the startup dimension def setup_and_check(self, data, title='', readonly=False, xlabels=None, ylabels=None): """ Setup ArrayEditor: return False if data is not supported, True otherwise """ self.data = data is_record_array = data.dtype.names is not None is_masked_array = isinstance(data, np.ma.MaskedArray) if data.size == 0: self.error(_("Array is empty")) return False if data.ndim > 3: self.error(_("Arrays with more than 3 dimensions are not supported")) return False if xlabels is not None and len(xlabels) != self.data.shape[1]: self.error(_("The 'xlabels' argument length do no match array " "column number")) return False if ylabels is not None and len(ylabels) != self.data.shape[0]: self.error(_("The 'ylabels' argument length do no match array row " "number")) return False if not is_record_array: dtn = data.dtype.name if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \ and not dtn.startswith('unicode'): arr = _("%s arrays") % data.dtype.name self.error(_("%s are currently not supported") % arr) return False self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - " + _("NumPy array") else: title = _("Array editor") if readonly: title += ' (' + _('read only') + ')' self.setWindowTitle(title) self.resize(600, 500) # Stack widget self.stack = QStackedWidget(self) if is_record_array: for name in data.dtype.names: self.stack.addWidget(ArrayEditorWidget(self, data[name], readonly, xlabels, ylabels)) elif is_masked_array: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels)) elif data.ndim == 3: pass else: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.arraywidget = self.stack.currentWidget() self.stack.currentChanged.connect(self.current_widget_changed) self.layout.addWidget(self.stack, 1, 0) # Buttons configuration btn_layout = QHBoxLayout() if is_record_array or is_masked_array or data.ndim == 3: if is_record_array: btn_layout.addWidget(QLabel(_("Record array fields:"))) names = [] for name in data.dtype.names: field = data.dtype.fields[name] text = name if len(field) >= 3: title = field[2] if not is_text_string(title): title = repr(title) text += ' - '+title names.append(text) else: names = [_('Masked data'), _('Data'), _('Mask')] if data.ndim == 3: # QSpinBox self.index_spin = QSpinBox(self, keyboardTracking=False) self.index_spin.valueChanged.connect(self.change_active_widget) # QComboBox names = [str(i) for i in range(3)] ra_combo = QComboBox(self) ra_combo.addItems(names) ra_combo.currentIndexChanged.connect(self.current_dim_changed) # Adding the widgets to layout label = QLabel(_("Axis:")) btn_layout.addWidget(label) btn_layout.addWidget(ra_combo) self.shape_label = QLabel() btn_layout.addWidget(self.shape_label) label = QLabel(_("Index:")) btn_layout.addWidget(label) btn_layout.addWidget(self.index_spin) self.slicing_label = QLabel() btn_layout.addWidget(self.slicing_label) # set the widget to display when launched self.current_dim_changed(self.last_dim) else: ra_combo = QComboBox(self) ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex) ra_combo.addItems(names) btn_layout.addWidget(ra_combo) if is_masked_array: label = QLabel(_("<u>Warning</u>: changes are applied separately")) label.setToolTip(_("For performance reasons, changes applied "\ "to masked array won't be reflected in "\ "array's data (and vice-versa).")) btn_layout.addWidget(label) btn_layout.addStretch() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btn_layout.addWidget(bbox) self.layout.addLayout(btn_layout, 2, 0) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) return True def current_widget_changed(self, index): self.arraywidget = self.stack.widget(index) def change_active_widget(self, index): """ This is implemented for handling negative values in index for 3d arrays, to give the same behavior as slicing """ string_index = [':']*3 string_index[self.last_dim] = '<font color=red>%i</font>' self.slicing_label.setText((r"Slicing: [" + ", ".join(string_index) + "]") % index) if index < 0: data_index = self.data.shape[self.last_dim] + index else: data_index = index slice_index = [slice(None)]*3 slice_index[self.last_dim] = data_index stack_index = self.dim_indexes[self.last_dim].get(data_index) if stack_index == None: stack_index = self.stack.count() self.stack.addWidget(ArrayEditorWidget(self, self.data[slice_index])) self.dim_indexes[self.last_dim][data_index] = stack_index self.stack.update() self.stack.setCurrentIndex(stack_index) def current_dim_changed(self, index): """ This change the active axis the array editor is plotting over in 3D """ self.last_dim = index string_size = ['%i']*3 string_size[index] = '<font color=red>%i</font>' self.shape_label.setText(('Shape: (' + ', '.join(string_size) + ') ') % self.data.shape) if self.index_spin.value() != 0: self.index_spin.setValue(0) else: # this is done since if the value is currently 0 it does not emit # currentIndexChanged(int) self.change_active_widget(0) self.index_spin.setRange(-self.data.shape[index], self.data.shape[index]-1) @Slot() def accept(self): """Reimplement Qt method""" for index in range(self.stack.count()): self.stack.widget(index).accept_changes() QDialog.accept(self) def get_value(self): """Return modified array -- this is *not* a copy""" # It is import to avoid accessing Qt C++ object as it has probably # already been destroyed, due to the Qt.WA_DeleteOnClose attribute return self.data def error(self, message): """An error occured, closing the dialog box""" QMessageBox.critical(self, _("Array editor"), message) self.setAttribute(Qt.WA_DeleteOnClose) self.reject() @Slot() def reject(self): """Reimplement Qt method""" if self.arraywidget is not None: for index in range(self.stack.count()): self.stack.widget(index).reject_changes() QDialog.reject(self)
class MixerPanel(QFrame): '''A color mixer to hook up to an image. You pass the image you the panel to operate on and it operates on that image in place. You also pass a callback to be called to trigger a refresh. This callback is called every time the mixer modifies your image.''' def __init__(self, img): QFrame.__init__(self) # self.setFrameStyle(QFrame.Box | QFrame.Sunken) self.img = img self.mixer = ColorMixer(self.img) self.callback = None #--------------------------------------------------------------- # ComboBox #--------------------------------------------------------------- self.combo_box_entries = ['RGB Color', 'HSV Color', 'Brightness/Contrast', 'Gamma', 'Gamma (Sigmoidal)'] self.combo_box = QComboBox() for entry in self.combo_box_entries: self.combo_box.addItem(entry) self.combo_box.currentIndexChanged.connect(self.combo_box_changed) #--------------------------------------------------------------- # RGB color sliders #--------------------------------------------------------------- # radio buttons self.rgb_add = QRadioButton('Additive') self.rgb_mul = QRadioButton('Multiplicative') self.rgb_mul.toggled.connect(self.rgb_radio_changed) self.rgb_add.toggled.connect(self.rgb_radio_changed) # sliders rs = IntelligentSlider('R', 0.51, -255, self.rgb_changed) gs = IntelligentSlider('G', 0.51, -255, self.rgb_changed) bs = IntelligentSlider('B', 0.51, -255, self.rgb_changed) self.rs = rs self.gs = gs self.bs = bs self.rgb_widget = QWidget() self.rgb_widget.layout = QGridLayout(self.rgb_widget) self.rgb_widget.layout.addWidget(self.rgb_add, 0, 0, 1, 3) self.rgb_widget.layout.addWidget(self.rgb_mul, 1, 0, 1, 3) self.rgb_widget.layout.addWidget(self.rs, 2, 0) self.rgb_widget.layout.addWidget(self.gs, 2, 1) self.rgb_widget.layout.addWidget(self.bs, 2, 2) #--------------------------------------------------------------- # HSV sliders #--------------------------------------------------------------- # radio buttons self.hsv_add = QRadioButton('Additive') self.hsv_mul = QRadioButton('Multiplicative') self.hsv_mul.toggled.connect(self.hsv_radio_changed) self.hsv_mul.toggled.connect(self.hsv_radio_changed) # sliders hs = IntelligentSlider('H', 0.36, -180, self.hsv_changed) ss = IntelligentSlider('S', 0.002, 0, self.hsv_changed) vs = IntelligentSlider('V', 0.002, 0, self.hsv_changed) self.hs = hs self.ss = ss self.vs = vs self.hsv_widget = QWidget() self.hsv_widget.layout = QGridLayout(self.hsv_widget) self.hsv_widget.layout.addWidget(self.hsv_add, 0, 0, 1, 3) self.hsv_widget.layout.addWidget(self.hsv_mul, 1, 0, 1, 3) self.hsv_widget.layout.addWidget(self.hs, 2, 0) self.hsv_widget.layout.addWidget(self.ss, 2, 1) self.hsv_widget.layout.addWidget(self.vs, 2, 2) #--------------------------------------------------------------- # Brightness/Contrast sliders #--------------------------------------------------------------- # sliders cont = IntelligentSlider('x', 0.002, 0, self.bright_changed) bright = IntelligentSlider('+', 0.51, -255, self.bright_changed) self.cont = cont self.bright = bright # layout self.bright_widget = QWidget() self.bright_widget.layout = QGridLayout(self.bright_widget) self.bright_widget.layout.addWidget(self.cont, 0, 0) self.bright_widget.layout.addWidget(self.bright, 0, 1) #---------------------------------------------------------------------- # Gamma Slider #---------------------------------------------------------------------- gamma = IntelligentSlider('gamma', 0.005, 0, self.gamma_changed) self.gamma = gamma # layout self.gamma_widget = QWidget() self.gamma_widget.layout = QGridLayout(self.gamma_widget) self.gamma_widget.layout.addWidget(self.gamma, 0, 0) #--------------------------------------------------------------- # Sigmoid Gamma sliders #--------------------------------------------------------------- # sliders alpha = IntelligentSlider('alpha', 0.011, 1, self.sig_gamma_changed) beta = IntelligentSlider('beta', 0.012, 0, self.sig_gamma_changed) self.a_gamma = alpha self.b_gamma = beta # layout self.sig_gamma_widget = QWidget() self.sig_gamma_widget.layout = QGridLayout(self.sig_gamma_widget) self.sig_gamma_widget.layout.addWidget(self.a_gamma, 0, 0) self.sig_gamma_widget.layout.addWidget(self.b_gamma, 0, 1) #--------------------------------------------------------------- # Buttons #--------------------------------------------------------------- self.commit_button = QPushButton('Commit') self.commit_button.clicked.connect(self.commit_changes) self.revert_button = QPushButton('Revert') self.revert_button.clicked.connect(self.revert_changes) #--------------------------------------------------------------- # Mixer Layout #--------------------------------------------------------------- self.sliders = QStackedWidget() self.sliders.addWidget(self.rgb_widget) self.sliders.addWidget(self.hsv_widget) self.sliders.addWidget(self.bright_widget) self.sliders.addWidget(self.gamma_widget) self.sliders.addWidget(self.sig_gamma_widget) self.layout = QGridLayout(self) self.layout.addWidget(self.combo_box, 0, 0) self.layout.addWidget(self.sliders, 1, 0) self.layout.addWidget(self.commit_button, 2, 0) self.layout.addWidget(self.revert_button, 3, 0) #--------------------------------------------------------------- # State Initialization #--------------------------------------------------------------- self.combo_box.setCurrentIndex(0) self.rgb_mul.setChecked(True) self.hsv_mul.setChecked(True) def set_callback(self, callback): self.callback = callback def combo_box_changed(self, index): self.sliders.setCurrentIndex(index) self.reset() def rgb_radio_changed(self): self.reset() def hsv_radio_changed(self): self.reset() def reset(self): self.reset_sliders() self.mixer.set_to_stateimg() if self.callback: self.callback() def reset_sliders(self): # handle changing the conversion factors necessary if self.rgb_add.isChecked(): self.rs.set_conv_fac(0.51, -255) self.rs.set_value(0) self.gs.set_conv_fac(0.51, -255) self.gs.set_value(0) self.bs.set_conv_fac(0.51, -255) self.bs.set_value(0) else: self.rs.set_conv_fac(0.002, 0) self.rs.set_value(1.) self.gs.set_conv_fac(0.002, 0) self.gs.set_value(1.) self.bs.set_conv_fac(0.002, 0) self.bs.set_value(1.) self.hs.set_value(0) if self.hsv_add.isChecked(): self.ss.set_conv_fac(0.002, -1) self.ss.set_value(0) self.vs.set_conv_fac(0.002, -1) self.vs.set_value(0) else: self.ss.set_conv_fac(0.002, 0) self.ss.set_value(1.) self.vs.set_conv_fac(0.002, 0) self.vs.set_value(1.) self.bright.set_value(0) self.cont.set_value(1.) self.gamma.set_value(1) self.a_gamma.set_value(1) self.b_gamma.set_value(0.5) def rgb_changed(self, name, val): if name == 'R': channel = self.mixer.RED elif name == 'G': channel = self.mixer.GREEN else: channel = self.mixer.BLUE if self.rgb_mul.isChecked(): self.mixer.multiply(channel, val) elif self.rgb_add.isChecked(): self.mixer.add(channel, val) else: pass if self.callback: self.callback() def hsv_changed(self, name, val): h = self.hs.val() s = self.ss.val() v = self.vs.val() if self.hsv_mul.isChecked(): self.mixer.hsv_multiply(h, s, v) elif self.hsv_add.isChecked(): self.mixer.hsv_add(h, s, v) else: pass if self.callback: self.callback() def bright_changed(self, name, val): b = self.bright.val() c = self.cont.val() self.mixer.brightness(c, b) if self.callback: self.callback() def gamma_changed(self, name, val): self.mixer.gamma(val) if self.callback: self.callback() def sig_gamma_changed(self, name, val): ag = self.a_gamma.val() bg = self.b_gamma.val() self.mixer.sigmoid_gamma(ag, bg) if self.callback: self.callback() def commit_changes(self): self.mixer.commit_changes() self.reset_sliders() def revert_changes(self): self.mixer.revert() self.reset_sliders() if self.callback: self.callback()
def __init__(self, img): QFrame.__init__(self) # self.setFrameStyle(QFrame.Box | QFrame.Sunken) self.img = img self.mixer = ColorMixer(self.img) self.callback = None #--------------------------------------------------------------- # ComboBox #--------------------------------------------------------------- self.combo_box_entries = ['RGB Color', 'HSV Color', 'Brightness/Contrast', 'Gamma', 'Gamma (Sigmoidal)'] self.combo_box = QComboBox() for entry in self.combo_box_entries: self.combo_box.addItem(entry) self.combo_box.currentIndexChanged.connect(self.combo_box_changed) #--------------------------------------------------------------- # RGB color sliders #--------------------------------------------------------------- # radio buttons self.rgb_add = QRadioButton('Additive') self.rgb_mul = QRadioButton('Multiplicative') self.rgb_mul.toggled.connect(self.rgb_radio_changed) self.rgb_add.toggled.connect(self.rgb_radio_changed) # sliders rs = IntelligentSlider('R', 0.51, -255, self.rgb_changed) gs = IntelligentSlider('G', 0.51, -255, self.rgb_changed) bs = IntelligentSlider('B', 0.51, -255, self.rgb_changed) self.rs = rs self.gs = gs self.bs = bs self.rgb_widget = QWidget() self.rgb_widget.layout = QGridLayout(self.rgb_widget) self.rgb_widget.layout.addWidget(self.rgb_add, 0, 0, 1, 3) self.rgb_widget.layout.addWidget(self.rgb_mul, 1, 0, 1, 3) self.rgb_widget.layout.addWidget(self.rs, 2, 0) self.rgb_widget.layout.addWidget(self.gs, 2, 1) self.rgb_widget.layout.addWidget(self.bs, 2, 2) #--------------------------------------------------------------- # HSV sliders #--------------------------------------------------------------- # radio buttons self.hsv_add = QRadioButton('Additive') self.hsv_mul = QRadioButton('Multiplicative') self.hsv_mul.toggled.connect(self.hsv_radio_changed) self.hsv_mul.toggled.connect(self.hsv_radio_changed) # sliders hs = IntelligentSlider('H', 0.36, -180, self.hsv_changed) ss = IntelligentSlider('S', 0.002, 0, self.hsv_changed) vs = IntelligentSlider('V', 0.002, 0, self.hsv_changed) self.hs = hs self.ss = ss self.vs = vs self.hsv_widget = QWidget() self.hsv_widget.layout = QGridLayout(self.hsv_widget) self.hsv_widget.layout.addWidget(self.hsv_add, 0, 0, 1, 3) self.hsv_widget.layout.addWidget(self.hsv_mul, 1, 0, 1, 3) self.hsv_widget.layout.addWidget(self.hs, 2, 0) self.hsv_widget.layout.addWidget(self.ss, 2, 1) self.hsv_widget.layout.addWidget(self.vs, 2, 2) #--------------------------------------------------------------- # Brightness/Contrast sliders #--------------------------------------------------------------- # sliders cont = IntelligentSlider('x', 0.002, 0, self.bright_changed) bright = IntelligentSlider('+', 0.51, -255, self.bright_changed) self.cont = cont self.bright = bright # layout self.bright_widget = QWidget() self.bright_widget.layout = QGridLayout(self.bright_widget) self.bright_widget.layout.addWidget(self.cont, 0, 0) self.bright_widget.layout.addWidget(self.bright, 0, 1) #---------------------------------------------------------------------- # Gamma Slider #---------------------------------------------------------------------- gamma = IntelligentSlider('gamma', 0.005, 0, self.gamma_changed) self.gamma = gamma # layout self.gamma_widget = QWidget() self.gamma_widget.layout = QGridLayout(self.gamma_widget) self.gamma_widget.layout.addWidget(self.gamma, 0, 0) #--------------------------------------------------------------- # Sigmoid Gamma sliders #--------------------------------------------------------------- # sliders alpha = IntelligentSlider('alpha', 0.011, 1, self.sig_gamma_changed) beta = IntelligentSlider('beta', 0.012, 0, self.sig_gamma_changed) self.a_gamma = alpha self.b_gamma = beta # layout self.sig_gamma_widget = QWidget() self.sig_gamma_widget.layout = QGridLayout(self.sig_gamma_widget) self.sig_gamma_widget.layout.addWidget(self.a_gamma, 0, 0) self.sig_gamma_widget.layout.addWidget(self.b_gamma, 0, 1) #--------------------------------------------------------------- # Buttons #--------------------------------------------------------------- self.commit_button = QPushButton('Commit') self.commit_button.clicked.connect(self.commit_changes) self.revert_button = QPushButton('Revert') self.revert_button.clicked.connect(self.revert_changes) #--------------------------------------------------------------- # Mixer Layout #--------------------------------------------------------------- self.sliders = QStackedWidget() self.sliders.addWidget(self.rgb_widget) self.sliders.addWidget(self.hsv_widget) self.sliders.addWidget(self.bright_widget) self.sliders.addWidget(self.gamma_widget) self.sliders.addWidget(self.sig_gamma_widget) self.layout = QGridLayout(self) self.layout.addWidget(self.combo_box, 0, 0) self.layout.addWidget(self.sliders, 1, 0) self.layout.addWidget(self.commit_button, 2, 0) self.layout.addWidget(self.revert_button, 3, 0) #--------------------------------------------------------------- # State Initialization #--------------------------------------------------------------- self.combo_box.setCurrentIndex(0) self.rgb_mul.setChecked(True) self.hsv_mul.setChecked(True)
class CalibrationWidget(ParameterWidget): def __init__(self, parent=None): ParameterWidget.__init__(self, _Calibration, parent) def _init_ui(self): # Widgets self._combobox = QComboBox() self._stack = QStackedWidget() # Layouts layout = ParameterWidget._init_ui(self) layout.addRow(self._combobox) layout.addRow(self._stack) # Register classes self._widget_indexes = {} for entry_point in iter_entry_points('pyhmsa_gui.spec.condition.calibration'): widget_class = entry_point.load(require=False) widget = widget_class() self._combobox.addItem(widget.accessibleName().title()) self._widget_indexes[widget.CLASS] = self._stack.addWidget(widget) widget.edited.connect(self.edited) # Signals self._combobox.currentIndexChanged.connect(self._on_combo_box) self._combobox.currentIndexChanged.connect(self.edited) return layout def _on_combo_box(self): # Old values oldwidget = self._stack.currentWidget() try: quantity = oldwidget._txt_quantity.text() except: quantity = None try: unit = oldwidget._txt_unit.text() except: unit = None # Change widget current_index = self._combobox.currentIndex() self._stack.setCurrentIndex(current_index) # Update values widget = self._stack.currentWidget() widget._txt_quantity.setText(quantity) widget._txt_unit.setText(unit) def parameter(self): return self._stack.currentWidget().calibration() def setParameter(self, calibration): index = self._widget_indexes[type(calibration)] self._combobox.setCurrentIndex(index) self._stack.setCurrentIndex(index) self._stack.currentWidget().setParameter(calibration) def calibration(self): return self.parameter() def setCalibration(self, calibration): self.setParameter(calibration) def setReadOnly(self, state): ParameterWidget.setReadOnly(self, state) self._combobox.setEnabled(not state) self._stack.currentWidget().setReadOnly(state) def isReadOnly(self): return ParameterWidget.isReadOnly(self) and \ not self._combobox.isEnabled() and \ self._stack.currentWidget().isReadOnly() def hasAcceptableInput(self): return ParameterWidget.hasAcceptableInput(self) and \ self._stack.currentWidget().hasAcceptableInput()
class ConfigDialog(QDialog): """Spyder configuration ('Preferences') dialog box""" # Signals check_settings = Signal() size_change = Signal(QSize) def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.pages_widget.setMinimumWidth(600) self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) self.contents_widget.setMinimumWidth(220) self.contents_widget.setMinimumHeight(400) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setStretchFactor(0, 1) hsplitter.setStretchFactor(1, 2) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots if self.main: self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf()) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def get_page(self, index=None): """Return page widget""" if index is None: widget = self.pages_widget.currentWidget() else: widget = self.pages_widget.widget(index) return widget.widget() @Slot() def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.get_page(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.get_page() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.get_page(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.check_settings.connect(widget.check_settings) widget.show_this_page.connect(lambda row=self.contents_widget.count(): self.contents_widget.setCurrentRow(row)) widget.apply_button_enabled.connect(self.apply_btn.setEnabled) scrollarea = QScrollArea(self) scrollarea.setWidgetResizable(True) scrollarea.setWidget(widget) self.pages_widget.addWidget(scrollarea) item = QListWidgetItem(self.contents_widget) try: item.setIcon(widget.get_icon()) except TypeError: pass item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.check_settings.emit() def resizeEvent(self, event): """ Reimplement Qt method to be able to save the widget's size from the main application """ QDialog.resizeEvent(self, event) self.size_change.emit(self.size())
def setup_and_check(self, data, title='', readonly=False, xlabels=None, ylabels=None): """ Setup ArrayEditor: return False if data is not supported, True otherwise """ self.data = data is_record_array = data.dtype.names is not None is_masked_array = isinstance(data, np.ma.MaskedArray) if data.size == 0: self.error(_("Array is empty")) return False if data.ndim > 3: self.error(_("Arrays with more than 3 dimensions are not supported")) return False if xlabels is not None and len(xlabels) != self.data.shape[1]: self.error(_("The 'xlabels' argument length do no match array " "column number")) return False if ylabels is not None and len(ylabels) != self.data.shape[0]: self.error(_("The 'ylabels' argument length do no match array row " "number")) return False if not is_record_array: dtn = data.dtype.name if dtn not in SUPPORTED_FORMATS and not dtn.startswith('str') \ and not dtn.startswith('unicode'): arr = _("%s arrays") % data.dtype.name self.error(_("%s are currently not supported") % arr) return False self.layout = QGridLayout() self.setLayout(self.layout) self.setWindowIcon(ima.icon('arredit')) if title: title = to_text_string(title) + " - " + _("NumPy array") else: title = _("Array editor") if readonly: title += ' (' + _('read only') + ')' self.setWindowTitle(title) self.resize(600, 500) # Stack widget self.stack = QStackedWidget(self) if is_record_array: for name in data.dtype.names: self.stack.addWidget(ArrayEditorWidget(self, data[name], readonly, xlabels, ylabels)) elif is_masked_array: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.data, readonly, xlabels, ylabels)) self.stack.addWidget(ArrayEditorWidget(self, data.mask, readonly, xlabels, ylabels)) elif data.ndim == 3: pass else: self.stack.addWidget(ArrayEditorWidget(self, data, readonly, xlabels, ylabels)) self.arraywidget = self.stack.currentWidget() self.stack.currentChanged.connect(self.current_widget_changed) self.layout.addWidget(self.stack, 1, 0) # Buttons configuration btn_layout = QHBoxLayout() if is_record_array or is_masked_array or data.ndim == 3: if is_record_array: btn_layout.addWidget(QLabel(_("Record array fields:"))) names = [] for name in data.dtype.names: field = data.dtype.fields[name] text = name if len(field) >= 3: title = field[2] if not is_text_string(title): title = repr(title) text += ' - '+title names.append(text) else: names = [_('Masked data'), _('Data'), _('Mask')] if data.ndim == 3: # QSpinBox self.index_spin = QSpinBox(self, keyboardTracking=False) self.index_spin.valueChanged.connect(self.change_active_widget) # QComboBox names = [str(i) for i in range(3)] ra_combo = QComboBox(self) ra_combo.addItems(names) ra_combo.currentIndexChanged.connect(self.current_dim_changed) # Adding the widgets to layout label = QLabel(_("Axis:")) btn_layout.addWidget(label) btn_layout.addWidget(ra_combo) self.shape_label = QLabel() btn_layout.addWidget(self.shape_label) label = QLabel(_("Index:")) btn_layout.addWidget(label) btn_layout.addWidget(self.index_spin) self.slicing_label = QLabel() btn_layout.addWidget(self.slicing_label) # set the widget to display when launched self.current_dim_changed(self.last_dim) else: ra_combo = QComboBox(self) ra_combo.currentIndexChanged.connect(self.stack.setCurrentIndex) ra_combo.addItems(names) btn_layout.addWidget(ra_combo) if is_masked_array: label = QLabel(_("<u>Warning</u>: changes are applied separately")) label.setToolTip(_("For performance reasons, changes applied "\ "to masked array won't be reflected in "\ "array's data (and vice-versa).")) btn_layout.addWidget(label) btn_layout.addStretch() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) btn_layout.addWidget(bbox) self.layout.addLayout(btn_layout, 2, 0) self.setMinimumSize(400, 300) # Make the dialog act as a window self.setWindowFlags(Qt.Window) return True
class VariableExplorer(SpyderPluginWidget): """Variable Explorer plugin.""" CONF_SECTION = 'variable_explorer' CONFIGWIDGET_CLASS = VariableExplorerConfigPage DISABLE_ACTIONS_WHEN_HIDDEN = False INITIAL_FREE_MEMORY_TIME_TRIGGER = 60 * 1000 # ms SECONDARY_FREE_MEMORY_TIME_TRIGGER = 180 * 1000 # ms sig_option_changed = Signal(str, object) def __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QVBoxLayout() layout.addWidget(self.stack) self.setLayout(layout) # Initialize plugin self.initialize_plugin() def get_settings(self): """ Retrieve all Variable Explorer configuration settings. Specifically, return the settings in CONF_SECTION with keys in REMOTE_SETTINGS, and the setting 'dataframe_format'. Returns: dict: settings """ settings = {} for name in REMOTE_SETTINGS: settings[name] = self.get_option(name) # dataframe_format is stored without percent sign in config # to avoid interference with ConfigParser's interpolation name = 'dataframe_format' settings[name] = '%{0}'.format(self.get_option(name)) return settings @Slot(str, object) def change_option(self, option_name, new_value): """ Change a config option. This function is called if sig_option_changed is received. If the option changed is the dataframe format, then the leading '%' character is stripped (because it can't be stored in the user config). Then, the signal is emitted again, so that the new value is saved in the user config. """ if option_name == 'dataframe_format': assert new_value.startswith('%') new_value = new_value[1:] self.sig_option_changed.emit(option_name, new_value) @Slot() def free_memory(self): """Free memory signal.""" self.main.free_memory() QTimer.singleShot(self.INITIAL_FREE_MEMORY_TIME_TRIGGER, lambda: self.main.free_memory()) QTimer.singleShot(self.SECONDARY_FREE_MEMORY_TIME_TRIGGER, lambda: self.main.free_memory()) # ----- Stack accesors ---------------------------------------------------- def set_current_widget(self, nsb): self.stack.setCurrentWidget(nsb) # We update the actions of the options button (cog menu) and we move # it to the layout of the current widget. self.refresh_actions() nsb.setup_options_button() def current_widget(self): return self.stack.currentWidget() def count(self): return self.stack.count() def remove_widget(self, nsb): self.stack.removeWidget(nsb) def add_widget(self, nsb): self.stack.addWidget(nsb) # ----- Public API -------------------------------------------------------- def add_shellwidget(self, shellwidget): """ Register shell with variable explorer. This function opens a new NamespaceBrowser for browsing the variables in the shell. """ shellwidget_id = id(shellwidget) if shellwidget_id not in self.shellwidgets: self.options_button.setVisible(True) nsb = NamespaceBrowser(self, options_button=self.options_button) nsb.set_shellwidget(shellwidget) nsb.setup(**self.get_settings()) nsb.sig_option_changed.connect(self.change_option) nsb.sig_free_memory.connect(self.free_memory) self.add_widget(nsb) self.shellwidgets[shellwidget_id] = nsb self.set_shellwidget_from_id(shellwidget_id) return nsb def remove_shellwidget(self, shellwidget_id): # If shellwidget_id is not in self.shellwidgets, it simply means # that shell was not a Python-based console (it was a terminal) if shellwidget_id in self.shellwidgets: nsb = self.shellwidgets.pop(shellwidget_id) self.remove_widget(nsb) nsb.close() def set_shellwidget_from_id(self, shellwidget_id): if shellwidget_id in self.shellwidgets: nsb = self.shellwidgets[shellwidget_id] self.set_current_widget(nsb) def import_data(self, fname): """Import data in current namespace""" if self.count(): nsb = self.current_widget() nsb.refresh_table() nsb.import_data(filenames=fname) if self.dockwidget and not self.ismaximized: self.dockwidget.setVisible(True) self.dockwidget.raise_() #------ SpyderPluginWidget API --------------------------------------------- def get_plugin_title(self): """Return widget title""" return _('Variable explorer') def get_plugin_icon(self): """Return plugin icon""" return ima.icon('dictedit') def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ return self.current_widget() def closing_plugin(self, cancelable=False): """Perform actions before parent main window is closed""" return True def refresh_plugin(self): """Refresh widget""" pass def get_plugin_actions(self): """Return a list of actions related to plugin""" return self.current_widget().actions if self.current_widget() else [] def register_plugin(self): """Register plugin in Spyder's main window""" self.main.add_dockwidget(self) def apply_plugin_settings(self, options): """Apply configuration file's plugin settings""" for nsb in list(self.shellwidgets.values()): nsb.setup(**self.get_settings())
class VariableExplorer(QWidget, SpyderPluginMixin): """ Variable Explorer Plugin """ CONF_SECTION = 'variable_explorer' CONFIGWIDGET_CLASS = VariableExplorerConfigPage sig_option_changed = Signal(str, object) def __init__(self, parent): QWidget.__init__(self, parent) SpyderPluginMixin.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QVBoxLayout() layout.addWidget(self.stack) self.setLayout(layout) # Initialize plugin self.initialize_plugin() @staticmethod def get_settings(): """ Return Variable Explorer settings dictionary (i.e. namespace browser settings according to Spyder's configuration file) """ settings = {} # CONF.load_from_ini() # necessary only when called from another process for name in REMOTE_SETTINGS: settings[name] = CONF.get(VariableExplorer.CONF_SECTION, name) return settings # ----- Stack accesors ---------------------------------------------------- def set_current_widget(self, nsb): self.stack.setCurrentWidget(nsb) def current_widget(self): return self.stack.currentWidget() def count(self): return self.stack.count() def remove_widget(self, nsb): self.stack.removeWidget(nsb) def add_widget(self, nsb): self.stack.addWidget(nsb) # ----- Public API -------------------------------------------------------- def add_shellwidget(self, shellwidget): shellwidget_id = id(shellwidget) # Add shell only once: this method may be called two times in a row # by the External console plugin (dev. convenience) from spyder.widgets.externalshell import systemshell if isinstance(shellwidget, systemshell.ExternalSystemShell): return if shellwidget_id not in self.shellwidgets: nsb = NamespaceBrowser(self) nsb.set_shellwidget(shellwidget) nsb.setup(**VariableExplorer.get_settings()) nsb.sig_option_changed.connect(self.sig_option_changed.emit) self.add_widget(nsb) self.shellwidgets[shellwidget_id] = nsb self.set_shellwidget_from_id(shellwidget_id) return nsb def remove_shellwidget(self, shellwidget_id): # If shellwidget_id is not in self.shellwidgets, it simply means # that shell was not a Python-based console (it was a terminal) if shellwidget_id in self.shellwidgets: nsb = self.shellwidgets.pop(shellwidget_id) self.remove_widget(nsb) nsb.close() def set_shellwidget_from_id(self, shellwidget_id): if shellwidget_id in self.shellwidgets: nsb = self.shellwidgets[shellwidget_id] self.set_current_widget(nsb) if self.isvisible: nsb.visibility_changed(True) def import_data(self, fname): """Import data in current namespace""" if self.count(): nsb = self.current_widget() nsb.refresh_table() nsb.import_data(filenames=fname) if self.dockwidget and not self.ismaximized: self.dockwidget.setVisible(True) self.dockwidget.raise_() #------ SpyderPluginMixin API --------------------------------------------- def visibility_changed(self, enable): """DockWidget visibility has changed""" SpyderPluginMixin.visibility_changed(self, enable) for nsb in list(self.shellwidgets.values()): nsb.visibility_changed(enable and nsb is self.current_widget()) #------ SpyderPluginWidget API --------------------------------------------- def get_plugin_title(self): """Return widget title""" return _('Variable explorer') def get_plugin_icon(self): """Return plugin icon""" return ima.icon('dictedit') def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ return self.current_widget() def closing_plugin(self, cancelable=False): """Perform actions before parent main window is closed""" return True def refresh_plugin(self): """Refresh widget""" pass def get_plugin_actions(self): """Return a list of actions related to plugin""" return [] def register_plugin(self): """Register plugin in Spyder's main window""" self.main.extconsole.set_variableexplorer(self) self.main.add_dockwidget(self) def apply_plugin_settings(self, options): """Apply configuration file's plugin settings""" for nsb in list(self.shellwidgets.values()): nsb.setup(**VariableExplorer.get_settings()) ar_timeout = self.get_option('autorefresh/timeout') for shellwidget in self.main.extconsole.shellwidgets: shellwidget.set_autorefresh_timeout(ar_timeout)
class Plots(SpyderPluginWidget): """Plots plugin.""" CONF_SECTION = 'plots' CONFIGWIDGET_CLASS = PlotsConfigPage DISABLE_ACTIONS_WHEN_HIDDEN = False sig_option_changed = Signal(str, object) def __init__(self, parent): SpyderPluginWidget.__init__(self, parent) # Widgets self.stack = QStackedWidget(self) self.shellwidgets = {} # Layout layout = QGridLayout(self) layout.addWidget(self.stack) # Initialize plugin self.initialize_plugin() def get_settings(self): """Retrieve all Plots configuration settings.""" return {name: self.get_option(name) for name in ['mute_inline_plotting', 'show_plot_outline']} # ---- Stack accesors def set_current_widget(self, fig_browser): """ Set the currently visible fig_browser in the stack widget, refresh the actions of the cog menu button and move it to the layout of the new fig_browser. """ self.stack.setCurrentWidget(fig_browser) # We update the actions of the options button (cog menu) and # we move it to the layout of the current widget. self.refresh_actions() fig_browser.setup_options_button() def current_widget(self): return self.stack.currentWidget() def count(self): return self.stack.count() def remove_widget(self, fig_browser): self.stack.removeWidget(fig_browser) def add_widget(self, fig_browser): self.stack.addWidget(fig_browser) # ---- Public API def add_shellwidget(self, shellwidget): """ Register shell with figure explorer. This function opens a new FigureBrowser for browsing the figures in the shell. """ shellwidget_id = id(shellwidget) if shellwidget_id not in self.shellwidgets: self.options_button.setVisible(True) fig_browser = FigureBrowser( self, options_button=self.options_button, background_color=MAIN_BG_COLOR) fig_browser.set_shellwidget(shellwidget) fig_browser.setup(**self.get_settings()) fig_browser.sig_option_changed.connect( self.sig_option_changed.emit) fig_browser.thumbnails_sb.redirect_stdio.connect( self.main.redirect_internalshell_stdio) self.add_widget(fig_browser) self.shellwidgets[shellwidget_id] = fig_browser self.set_shellwidget_from_id(shellwidget_id) return fig_browser def remove_shellwidget(self, shellwidget_id): # If shellwidget_id is not in self.shellwidgets, it simply means # that shell was not a Python-based console (it was a terminal) if shellwidget_id in self.shellwidgets: fig_browser = self.shellwidgets.pop(shellwidget_id) self.remove_widget(fig_browser) fig_browser.close() def set_shellwidget_from_id(self, shellwidget_id): if shellwidget_id in self.shellwidgets: fig_browser = self.shellwidgets[shellwidget_id] self.set_current_widget(fig_browser) # ---- SpyderPluginWidget API def get_plugin_title(self): """Return widget title""" return _('Plots') def get_plugin_icon(self): """Return plugin icon""" return ima.icon('hist') def get_focus_widget(self): """ Return the widget to give focus to when this plugin's dockwidget is raised on top-level """ return self.current_widget() def closing_plugin(self, cancelable=False): """Perform actions before parent main window is closed""" return True def refresh_plugin(self): """Refresh widget""" pass def get_plugin_actions(self): """Return a list of actions related to plugin""" return self.current_widget().actions if self.current_widget() else [] def register_plugin(self): """Register plugin in Spyder's main window""" self.main.add_dockwidget(self) def apply_plugin_settings(self, options): """Apply configuration file's plugin settings""" for fig_browser in list(self.shellwidgets.values()): fig_browser.setup(**self.get_settings())