def __init__(self, parent=None, logname=None, level=logging.NOTSET): QWidget.__init__(self, parent=parent) # Create Widgets self.label = QLabel('Minimum displayed log level: ', parent=self) self.combo = QComboBox(parent=self) self.text = QPlainTextEdit(parent=self) self.text.setReadOnly(True) self.clear_btn = QPushButton("Clear", parent=self) # Create layout layout = QVBoxLayout() level_control = QHBoxLayout() level_control.addWidget(self.label) level_control.addWidget(self.combo) layout.addLayout(level_control) layout.addWidget(self.text) layout.addWidget(self.clear_btn) self.setLayout(layout) # Allow QCombobox to control log level for log_level, value in LogLevels.as_dict().items(): self.combo.addItem(log_level, value) self.combo.currentIndexChanged[str].connect(self.setLevel) # Allow QPushButton to clear log text self.clear_btn.clicked.connect(self.clear) # Create a handler with the default format self.handler = GuiHandler(level=level, parent=self) self.logFormat = self.default_format self.handler.message.connect(self.write) # Create logger. Either as a root or given logname self.log = None self.level = None self.logName = logname or '' self.logLevel = level self.destroyed.connect(functools.partial(logger_destroyed, self.log))
def __init__(self, parent): QWidget.__init__(self, parent) self.shellwidget = None self.is_internal_shell = None self.ipyclient = None self.is_ipykernel = None self.is_visible = True self.setup_in_progress = None # Remote dict editor settings self.check_all = None self.exclude_private = None self.exclude_uppercase = None self.exclude_capitalized = None self.exclude_unsupported = None self.excluded_names = None self.truncate = None self.minmax = None self.remote_editing = None self.autorefresh = None self.editor = None self.exclude_private_action = None self.exclude_uppercase_action = None self.exclude_capitalized_action = None self.exclude_unsupported_action = None self.filename = None
def create_controls(self): self.btn_start = QPushButton(tr("Start")) self.btn_stop = QPushButton(tr("Stop")) self.btn_stop.setEnabled(False) self.btn_start.clicked.connect(self.start_recording) self.btn_stop.clicked.connect(self.stop_recording) self.chk_actions = QCheckBox(tr("Actions")) self.chk_code = QCheckBox(tr("Code")) for c in [self.chk_actions, self.chk_code]: c.setChecked(True) c.toggled.connect(self.update_filter) hbox = QHBoxLayout() for w in [self.btn_start, self.btn_stop]: hbox.addWidget(w) hbox2 = QHBoxLayout() for w in [self.chk_actions, self.chk_code]: hbox2.addWidget(w) vbox = QVBoxLayout() vbox.addLayout(hbox) vbox.addLayout(hbox2) wrap = QWidget() wrap.setLayout(vbox) height = vbox.sizeHint().height() wrap.setFixedHeight(height) self.setWidget(wrap)
def __init__(self, parent=None, init_channel=None): QWidget.__init__(self, parent) PyDMWidget.__init__(self, init_channel=init_channel) self.value = 0 self.setLayout(QGridLayout(self)) self._on_color = QColor(0, 255, 0) self._off_color = QColor(100, 100, 100) self._disconnected_color = QColor(255, 255, 255) self._invalid_color = QColor(255, 0, 255) self._pen_style = Qt.SolidLine self._line_pen = QPen(self._pen_style) self._orientation = Qt.Vertical # This is kind of ridiculous, importing QTabWidget just to get a 4-item enum thats usable in Designer. # PyQt5 lets you define custom enums that you can use in designer with QtCore.Q_ENUMS(), doesn't exist in PyQt4. self._labels = [] self._show_labels = True self._label_position = QTabWidget.East self._num_bits = 1 self._indicators = [] self._circles = False self.set_spacing() self.layout().setOriginCorner(Qt.TopLeftCorner) self._big_endian = False self._shift = 0 self.numBits = 1 # Need to set the property to initialize
def __init__(self, parent): QWidget.__init__(self, parent) self._parent = parent self.cp = CondaProcess(self) # Widgets self.button_get_conda_version = QPushButton('get_conda_version') self.button_info = QPushButton('info') self.button_get_envs = QPushButton('get envs') self.button_install = QPushButton('install') self.button_package_info = QPushButton('package info') self.button_linked = QPushButton('linked') self.button_pip = QPushButton('pip') self.button_pip_remove = QPushButton('pip-remove') self.widgets = [self.button_get_conda_version, self.button_info, self.button_get_envs, self.button_install, self.button_package_info, self.button_linked, self.button_pip] # Layout setup layout_top = QHBoxLayout() layout_top.addWidget(self.button_get_conda_version) layout_top.addWidget(self.button_get_envs) layout_top.addWidget(self.button_info) layout_top.addWidget(self.button_install) layout_top.addWidget(self.button_package_info) layout_middle = QHBoxLayout() layout_middle.addWidget(self.button_linked) layout_bottom = QHBoxLayout() layout_bottom.addWidget(self.button_pip) layout_bottom.addWidget(self.button_pip_remove) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addLayout(layout_middle) layout.addLayout(layout_bottom) self.setLayout(layout) # Signals self.cp.sig_started.connect(self.disable_widgets) self.cp.sig_finished.connect(self.on_finished) self.cp.sig_finished.connect(self.enable_widgets) self.button_get_conda_version.clicked.connect( self.cp.get_conda_version) self.button_get_envs.clicked.connect(self.cp.get_envs) self.button_info.clicked.connect(self.cp.info) self.button_install.clicked.connect(self.cp.install) self.button_package_info.clicked.connect( lambda: self.cp.package_info('spyder')) self.button_linked.clicked.connect( lambda: self.cp.linked(self.cp.ROOT_PREFIX)) self.button_pip.clicked.connect(lambda: self.cp.pip(name='root')) self.button_pip_remove.clicked.connect( lambda: self.cp.pip_remove(name='root', pkgs=['grequests']))
def __init__(self, parent, name, script="", filemodified=0): QWidget.__init__(self) self.parent = parent self.tabWidget = self.parent.ui.tabWidget self.gridlayout = QGridLayout(self) self._dirty = False self.initialize_editor() self.gridlayout.addWidget(self.editor) self.setAcceptDrops(True) self.filename = name self.filemodified = filemodified if self.is_file(): self.title = os.path.basename(name) # if self.equals_saved(): # self.filemodified = os.path.getmtime(self.filename) else: self.filename = "" self.title = name # Show this file in the self.editor self.editor.setText(script) self.clean_txt = self.saved() self.update_dirty() self.editor.keyPressEvent = self.key_press_event
def __init__(self, name, a, b, callback): QWidget.__init__(self) self.name = name self.callback = callback self.a = a self.b = b self.manually_triggered = False self.slider = QSlider() self.slider.setRange(0, 1000) self.slider.setValue(500) self.slider.valueChanged.connect(self.slider_changed) self.name_label = QLabel() self.name_label.setText(self.name) self.name_label.setAlignment(QtCore.Qt.AlignCenter) self.value_label = QLabel() self.value_label.setText('%2.2f' % (self.slider.value() * self.a + self.b)) self.value_label.setAlignment(QtCore.Qt.AlignCenter) self.layout = QGridLayout(self) self.layout.addWidget(self.name_label, 0, 0) self.layout.addWidget(self.slider, 1, 0, QtCore.Qt.AlignHCenter) self.layout.addWidget(self.value_label, 2, 0)
def show(self, hide_replace=True): """Overrides Qt Method""" QWidget.show(self) self.visibility_changed.emit(True) self.change_number_matches() if self.editor is not None: if hide_replace: if self.replace_widgets[0].isVisible(): self.hide_replace() text = self.editor.get_selected_text() # When selecting several lines, and replace box is activated the # text won't be replaced for the selection if hide_replace or len(text.splitlines())<=1: highlighted = True # If no text is highlighted for search, use whatever word is # under the cursor if not text: highlighted = False try: cursor = self.editor.textCursor() cursor.select(QTextCursor.WordUnderCursor) text = to_text_string(cursor.selectedText()) except AttributeError: # We can't do this for all widgets, e.g. WebView's pass # Now that text value is sorted out, use it for the search if text and not self.search_text.currentText() or highlighted: self.search_text.setEditText(text) self.search_text.lineEdit().selectAll() self.refresh() else: self.search_text.lineEdit().selectAll() self.search_text.setFocus()
def __init__(self, parent, name_filters=[], show_all=True, show_hscrollbar=True, options_button=None): QWidget.__init__(self, parent) self.name_filters = name_filters self.show_all = show_all self.show_hscrollbar = show_hscrollbar self.treewidget = ExplorerTreeWidget(self, self.show_hscrollbar) self.treewidget.setup(name_filters=self.name_filters, show_all=self.show_all) self.treewidget.setup_view() self.treewidget.hide() self.emptywidget = ExplorerTreeWidget(self) if options_button: btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) btn_layout.addStretch() btn_layout.addWidget(options_button, Qt.AlignRight) layout = create_plugin_layout(btn_layout) else: layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.emptywidget) layout.addWidget(self.treewidget) self.setLayout(layout)
def show(self): """Overrides Qt Method""" QWidget.show(self) self.visibility_changed.emit(True) if self.editor is not None: text = self.editor.get_selected_text() # If no text is highlighted for search, use whatever word is under # the cursor if not text: try: cursor = self.editor.textCursor() cursor.select(QTextCursor.WordUnderCursor) text = to_text_string(cursor.selectedText()) except AttributeError: # We can't do this for all widgets, e.g. WebView's pass # Now that text value is sorted out, use it for the search if text: self.search_text.setEditText(text) self.search_text.lineEdit().selectAll() self.refresh() else: self.search_text.lineEdit().selectAll() self.search_text.setFocus()
def __init__(self, parent): QWidget.__init__(self, parent) vert_layout = QVBoxLayout() # Type frame type_layout = QHBoxLayout() type_label = QLabel(_("Import as")) type_layout.addWidget(type_label) self.array_btn = array_btn = QRadioButton(_("array")) array_btn.setEnabled(ndarray is not FakeObject) array_btn.setChecked(ndarray is not FakeObject) type_layout.addWidget(array_btn) list_btn = QRadioButton(_("list")) list_btn.setChecked(not array_btn.isChecked()) type_layout.addWidget(list_btn) if pd: self.df_btn = df_btn = QRadioButton(_("DataFrame")) df_btn.setChecked(False) type_layout.addWidget(df_btn) h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) type_layout.addItem(h_spacer) type_frame = QFrame() type_frame.setLayout(type_layout) self._table_view = PreviewTable(self) vert_layout.addWidget(type_frame) vert_layout.addWidget(self._table_view) self.setLayout(vert_layout)
def __init__(self): QWidget.__init__(self) vlayout = QVBoxLayout() self.setLayout(vlayout) self.explorer = ProjectExplorerWidget(None, show_all=True) self.explorer.setup_project(osp.dirname(osp.abspath(__file__))) vlayout.addWidget(self.explorer) hlayout1 = QHBoxLayout() vlayout.addLayout(hlayout1) label = QLabel("<b>Open file:</b>") label.setAlignment(Qt.AlignRight) hlayout1.addWidget(label) self.label1 = QLabel() hlayout1.addWidget(self.label1) self.explorer.sig_open_file.connect(self.label1.setText) hlayout3 = QHBoxLayout() vlayout.addLayout(hlayout3) label = QLabel("<b>Option changed:</b>") label.setAlignment(Qt.AlignRight) hlayout3.addWidget(label) self.label3 = QLabel() hlayout3.addWidget(self.label3) self.explorer.sig_option_changed.connect( lambda x, y: self.label3.setText('option_changed: %r, %r' % (x, y)))
def __init__(self, parent=None, show_fullpath=True, fullpath_sorting=True, show_all_files=True, show_comments=True, options_button=None): QWidget.__init__(self, parent) self.treewidget = OutlineExplorerTreeWidget(self, show_fullpath=show_fullpath, fullpath_sorting=fullpath_sorting, show_all_files=show_all_files, show_comments=show_comments) self.visibility_action = create_action(self, _("Show/hide outline explorer"), icon='outline_explorer_vis.png', toggled=self.toggle_visibility) self.visibility_action.setChecked(True) btn_layout = QHBoxLayout() for btn in self.setup_buttons(): btn.setAutoRaise(True) btn.setIconSize(QSize(16, 16)) btn_layout.addWidget(btn) if options_button: btn_layout.addStretch() btn_layout.addWidget(options_button, Qt.AlignRight) layout = create_plugin_layout(btn_layout, self.treewidget) self.setLayout(layout)
def create_combobox(self, text, choices, option, default=NoDefault, tip=None, restart=False): """choices: couples (name, key)""" label = QLabel(text) combobox = QComboBox() if tip is not None: combobox.setToolTip(tip) for name, key in choices: if not (name is None and key is None): combobox.addItem(name, to_qvariant(key)) # Insert separators count = 0 for index, item in enumerate(choices): name, key = item if name is None and key is None: combobox.insertSeparator(index + count) count += 1 self.comboboxes[combobox] = (option, default) layout = QHBoxLayout() layout.addWidget(label) layout.addWidget(combobox) layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.label = label widget.combobox = combobox widget.setLayout(layout) combobox.restart_required = restart combobox.label_text = text return widget
def create_scedit(self, text, option, default=NoDefault, tip=None, without_layout=False): label = QLabel(text) clayout = ColorLayout(QColor(Qt.black), self) clayout.lineedit.setMaximumWidth(80) if tip is not None: clayout.setToolTip(tip) cb_bold = QCheckBox() cb_bold.setIcon(ima.icon('bold')) cb_bold.setToolTip(_("Bold")) cb_italic = QCheckBox() cb_italic.setIcon(ima.icon('italic')) cb_italic.setToolTip(_("Italic")) self.scedits[(clayout, cb_bold, cb_italic)] = (option, default) if without_layout: return label, clayout, cb_bold, cb_italic layout = QHBoxLayout() layout.addWidget(label) layout.addLayout(clayout) layout.addSpacing(10) layout.addWidget(cb_bold) layout.addWidget(cb_italic) layout.addStretch(1) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.setLayout(layout) return widget
def __init__(self, parent=None, show_fullpath=True, fullpath_sorting=True, show_all_files=True, show_comments=True): QWidget.__init__(self, parent) self.treewidget = OutlineExplorerTreeWidget(self, show_fullpath=show_fullpath, fullpath_sorting=fullpath_sorting, show_all_files=show_all_files, show_comments=show_comments) self.visibility_action = create_action(self, _("Show/hide outline explorer"), icon='outline_explorer_vis.png', toggled=self.toggle_visibility) self.visibility_action.setChecked(True) btn_layout = QHBoxLayout() btn_layout.setAlignment(Qt.AlignLeft) for btn in self.setup_buttons(): btn_layout.addWidget(btn) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(btn_layout) layout.addWidget(self.treewidget) self.setLayout(layout)
def create_file_combobox(self, text, choices, option, default=NoDefault, tip=None, restart=False, filters=None, adjust_to_contents=False, default_line_edit=False): """choices: couples (name, key)""" combobox = FileComboBox(self, adjust_to_contents=adjust_to_contents, default_line_edit=default_line_edit) combobox.restart_required = restart combobox.label_text = text edit = combobox.lineEdit() edit.label_text = text edit.restart_required = restart self.lineedits[edit] = (option, default) if tip is not None: combobox.setToolTip(tip) combobox.addItems(choices) msg = _('Invalid file path') self.validate_data[edit] = (osp.isfile, msg) browse_btn = QPushButton(ima.icon('FileIcon'), '', self) browse_btn.setToolTip(_("Select file")) browse_btn.clicked.connect(lambda: self.select_file(edit, filters)) layout = QGridLayout() layout.addWidget(combobox, 0, 0, 0, 9) layout.addWidget(browse_btn, 0, 10) layout.setContentsMargins(0, 0, 0, 0) widget = QWidget(self) widget.combobox = combobox widget.browse_btn = browse_btn widget.setLayout(layout) return widget
def __init__(self, parent=None, state=None, settings=None, data_type=None, ui_class=None, data_proxy=None): QWidget.__init__(self, parent) self._layout = QHBoxLayout() self.setLayout(self._layout) if ui_class is not None: self._content = ui_class(self) self._layout.addWidget(self._content) # Data filter for file dialog self._data_type="Data files (*.xml)" if data_type is not None: self._data_type = data_type # General GUI settings if settings is None: settings = GeneralSettings() self._settings = settings if ui_class is not None: self.setLayout(self._layout) self.initialize_content() self._instrument_view = None self._data_set_viewed = '' self._data_proxy = data_proxy self._has_instrument_view = HAS_INSTRUMENT_VIEW and self._data_proxy is not None self._is_running = True
def __init__(self, counts, colormap): QWidget.__init__(self) self._validate_input(counts, colormap) self.counts = counts self.n = np.sum(self.counts) self.colormap = colormap self.setMinimumSize(100, 50)
def __init__(self, parent, options_button=None, plugin_actions=[]): QWidget.__init__(self, parent) self.shellwidget = None self.is_visible = True self.setup_in_progress = None # Remote dict editor settings self.check_all = None self.exclude_private = None self.exclude_uppercase = None self.exclude_capitalized = None self.exclude_unsupported = None self.excluded_names = None self.minmax = None # Other setting self.dataframe_format = None self.editor = None self.exclude_private_action = None self.exclude_uppercase_action = None self.exclude_capitalized_action = None self.exclude_unsupported_action = None self.options_button = options_button self.actions = None self.plugin_actions = plugin_actions self.filename = None
def __init__(self, parent=None): QWidget.__init__(self, parent) # Widgets, layouts and signals self._group = QButtonGroup() layout = QGridLayout() layout.setSpacing(0) ## Element for z, position in _ELEMENT_POSITIONS.items(): widget = ElementPushButton(z) widget.setCheckable(True) layout.addWidget(widget, *position) self._group.addButton(widget, z) ## Labels layout.addWidget(QLabel(''), 7, 0) # Dummy layout.addWidget(QLabel('*'), 5, 2, Qt.AlignRight) layout.addWidget(QLabel('*'), 8, 2, Qt.AlignRight) layout.addWidget(QLabel('**'), 6, 2, Qt.AlignRight) layout.addWidget(QLabel('**'), 9, 2, Qt.AlignRight) for row in [0, 1, 2, 3, 4, 5, 6, 8, 9]: layout.setRowStretch(row, 1) self.setLayout(layout) # Signals self._group.buttonClicked.connect(self.selectionChanged) # Default self.setColorFunction(_category_color_function)
def __init__(self, editor_stack): """Main Window Mock constructor.""" QWidget.__init__(self, None) self.plugin_focus_changed = Mock() self.editor = EditorMock(editor_stack) layout = QVBoxLayout() layout.addWidget(self.editor) self.setLayout(layout)
def __init__(self, parent): QWidget.__init__(self, parent) self._parent = parent self.cp = CondaProcess(self) # Widgets self.button_get_conda_version = QPushButton("get_conda_version") self.button_info = QPushButton("info") self.button_get_envs = QPushButton("get envs") self.button_install = QPushButton("install") self.button_package_info = QPushButton("package info") self.button_linked = QPushButton("linked") self.button_pip = QPushButton("pip") self.widgets = [ self.button_get_conda_version, self.button_info, self.button_get_envs, self.button_install, self.button_package_info, self.button_linked, self.button_pip, ] # Layout setup layout_top = QHBoxLayout() layout_top.addWidget(self.button_get_conda_version) layout_top.addWidget(self.button_get_envs) layout_top.addWidget(self.button_info) layout_top.addWidget(self.button_install) layout_top.addWidget(self.button_package_info) layout_middle = QHBoxLayout() layout_middle.addWidget(self.button_linked) layout_bottom = QHBoxLayout() layout_bottom.addWidget(self.button_pip) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addLayout(layout_middle) layout.addLayout(layout_bottom) self.setLayout(layout) # Signals self.cp.sig_started.connect(self.disable_widgets) self.cp.sig_finished.connect(self.on_finished) self.cp.sig_finished.connect(self.enable_widgets) self.button_get_conda_version.clicked.connect(self.cp.get_conda_version) self.button_get_envs.clicked.connect(self.cp.get_envs) self.button_info.clicked.connect(self.cp.info) self.button_install.clicked.connect(self.cp.install) self.button_package_info.clicked.connect(lambda: self.cp.package_info("spyder")) self.button_linked.clicked.connect(lambda: self.cp.linked(self.cp.ROOT_PREFIX)) self.button_pip.clicked.connect(lambda: self.cp.pip("root"))
def __init__(self, parent=None): QWidget.__init__(self, parent) vlayout = QVBoxLayout() self.setLayout(vlayout) self.treewidget = FilteredDirView(self) self.treewidget.setup_view() self.treewidget.set_root_path(osp.dirname(osp.abspath(__file__))) self.treewidget.set_folder_names(['variableexplorer', 'sourcecode']) vlayout.addWidget(self.treewidget)
def __init__(self, parent, name_filters=[], show_all=True, show_hscrollbar=True): QWidget.__init__(self, parent) self.treewidget = None self.emptywidget = None self.name_filters = name_filters self.show_all = show_all self.show_hscrollbar = show_hscrollbar self.setup_layout()
def create_tab(self, *widgets): """Create simple tab widget page: widgets added in a vertical layout""" widget = QWidget() layout = QVBoxLayout() for widg in widgets: layout.addWidget(widg) layout.addStretch(1) widget.setLayout(layout) return widget
def _get_update_list(self, names): w = QWidget() vbox = QVBoxLayout() vbox.addWidget(QLabel(tr("The following updates are available. Do you " "want to update them?"))) for n in names: vbox.addWidget(QCheckBox(n)) w.setLayout(vbox) return w
def hide(self): """Overrides Qt Method""" for widget in self.replace_widgets: widget.hide() QWidget.hide(self) self.visibility_changed.emit(False) if self.editor is not None: self.editor.setFocus() self.clear_matches()
def _create_settings_widgets(self, settings): """ Create a widget for a settings instance, containing label/editor pairs for each setting in the current level of the passed QSettings instance. The key of the setting is used as the label, but it's capitalized and underscores are replaced by spaces. """ wrap = QWidget(self) form = QFormLayout() hint_lookup = Settings() for k in settings.allKeys(): if k.startswith("_"): continue # Ignore hidden keys v = settings.value(k) # Read value label = k.capitalize().replace('_', ' ') abs_key = settings.group() + '/' + k self._initial_values[abs_key] = v # Store initial value hints = hint_lookup.get_enum_hint(abs_key) # Check for enum hints # Create a fitting editor widget based on value type: if hints is not None: w = QComboBox() w.addItems(hints) w.setEditable(True) w.setEditText(v) w.editTextChanged.connect(partial(self._on_setting_changed, abs_key, w)) elif isinstance(v, str): if v.lower() in ('true', 'false'): w = QCheckBox() w.setChecked(v.lower() == 'true') w.toggled.connect(partial(self._on_setting_changed, abs_key, w)) else: w = QLineEdit(v) w.textChanged.connect(partial(self._on_setting_changed, abs_key, w)) elif isinstance(v, int): w = QSpinBox() w.setRange(np.iinfo(np.int32).min, np.iinfo(np.int32).max) w.setValue(v) w.valueChanged.connect(partial(self._on_setting_changed, abs_key, w)) elif isinstance(v, float): w = QDoubleSpinBox() w.setRange(np.finfo(np.float32).min, np.finfo(np.float32).max) w.setValue(v) w.valueChanged.connect(partial(self._on_setting_changed, abs_key, w)) else: w = QLineEdit(str(v)) w.textChanged.connect(partial(self._on_setting_changed, abs_key, w)) self._lut[abs_key] = w form.addRow(label, w) wrap.setLayout(form) return wrap
def __init__(self, parent): QWidget.__init__(self, parent) self.parent = parent # Variables to adjust self.duration_canvas = [666, 666] self.duration_tips = [333, 333] self.opacity_canvas = [0.0, 0.7] self.opacity_tips = [0.0, 1.0] self.color = Qt.black self.easing_curve = [QEasingCurve.Linear] self.current_step = 0 self.step_current = 0 self.steps = 0 self.canvas = None self.tips = None self.frames = None self.spy_window = None self.widgets = None self.dockwidgets = None self.decoration = None self.run = None self.is_tour_set = False # Widgets self.canvas = FadingCanvas(self.parent, self.opacity_canvas, self.duration_canvas, self.easing_curve, self.color) self.tips = FadingTipBox(self.parent, self.opacity_tips, self.duration_tips, self.easing_curve) # Widgets setup # Needed to fix issue #2204 self.setAttribute(Qt.WA_TransparentForMouseEvents) # Signals and slots self.tips.button_next.clicked.connect(self.next_step) self.tips.button_previous.clicked.connect(self.previous_step) self.tips.button_close.clicked.connect(self.close_tour) self.tips.button_run.clicked.connect(self.run_code) self.tips.button_home.clicked.connect(self.first_step) self.tips.button_end.clicked.connect(self.last_step) self.tips.button_run.clicked.connect( lambda: self.tips.button_run.setDisabled(True)) self.tips.combo_title.currentIndexChanged.connect(self.go_to_step) # Main window move or resize self.parent.sig_resized.connect(self._resized) self.parent.sig_moved.connect(self._moved) # To capture the arrow keys that allow moving the tour self.tips.sig_key_pressed.connect(self._key_pressed)
def setup_page(self): self.ICON = ima.icon('genprefs') newcb = self.create_checkbox # --- Advanced # Remove disabled languages language_codes = LANGUAGE_CODES.copy() for lang in DISABLED_LANGUAGES: language_codes.pop(lang) languages = language_codes.items() language_choices = sorted([(val, key) for key, val in languages]) language_combo = self.create_combobox(_('Language:'), language_choices, 'interface_language', restart=True) opengl_options = ['Automatic', 'Desktop', 'Software', 'GLES'] opengl_choices = list( zip(opengl_options, [c.lower() for c in opengl_options])) opengl_combo = self.create_combobox(_('Rendering engine:'), opengl_choices, 'opengl', restart=True) single_instance_box = newcb(_("Use a single instance"), 'single_instance', tip=_("Set this to open external<br> " "Python files in an already running " "instance (Requires a restart)")) prompt_box = newcb(_("Prompt when exiting"), 'prompt_on_exit') popup_console_box = newcb( _("Show internal Spyder errors to report " "them to Github"), 'show_internal_errors') check_updates = newcb(_("Check for updates on startup"), 'check_updates_on_startup') # Decide if it's possible to activate or not single instance mode if running_in_mac_app(): self.set_option("single_instance", True) single_instance_box.setEnabled(False) comboboxes_advanced_layout = QHBoxLayout() cbs_adv_grid = QGridLayout() cbs_adv_grid.addWidget(language_combo.label, 0, 0) cbs_adv_grid.addWidget(language_combo.combobox, 0, 1) cbs_adv_grid.addWidget(opengl_combo.label, 1, 0) cbs_adv_grid.addWidget(opengl_combo.combobox, 1, 1) comboboxes_advanced_layout.addLayout(cbs_adv_grid) comboboxes_advanced_layout.addStretch(1) advanced_layout = QVBoxLayout() advanced_layout.addLayout(comboboxes_advanced_layout) advanced_layout.addWidget(single_instance_box) advanced_layout.addWidget(prompt_box) advanced_layout.addWidget(popup_console_box) advanced_layout.addWidget(check_updates) advanced_widget = QWidget() advanced_widget.setLayout(advanced_layout) # --- Panes interface_group = QGroupBox(_("Panes")) verttabs_box = newcb(_("Vertical tabs in panes"), 'vertical_tabs') margin_box = newcb(_("Custom margin for panes:"), 'use_custom_margin') margin_spin = self.create_spinbox("", _("pixels"), 'custom_margin', default=0, min_=0, max_=30) margin_box.toggled.connect(margin_spin.spinbox.setEnabled) margin_box.toggled.connect(margin_spin.slabel.setEnabled) margin_spin.spinbox.setEnabled(self.get_option('use_custom_margin')) margin_spin.slabel.setEnabled(self.get_option('use_custom_margin')) cursor_box = newcb(_("Cursor blinking:"), 'use_custom_cursor_blinking') cursor_spin = self.create_spinbox( "", _("ms"), 'custom_cursor_blinking', default=QApplication.cursorFlashTime(), min_=0, max_=5000, step=100) cursor_box.toggled.connect(cursor_spin.spinbox.setEnabled) cursor_box.toggled.connect(cursor_spin.slabel.setEnabled) cursor_spin.spinbox.setEnabled( self.get_option('use_custom_cursor_blinking')) cursor_spin.slabel.setEnabled( self.get_option('use_custom_cursor_blinking')) margins_cursor_layout = QGridLayout() margins_cursor_layout.addWidget(margin_box, 0, 0) margins_cursor_layout.addWidget(margin_spin.spinbox, 0, 1) margins_cursor_layout.addWidget(margin_spin.slabel, 0, 2) margins_cursor_layout.addWidget(cursor_box, 1, 0) margins_cursor_layout.addWidget(cursor_spin.spinbox, 1, 1) margins_cursor_layout.addWidget(cursor_spin.slabel, 1, 2) margins_cursor_layout.setColumnStretch(2, 100) # Layout interface interface_layout = QVBoxLayout() interface_layout.addWidget(verttabs_box) interface_layout.addLayout(margins_cursor_layout) interface_group.setLayout(interface_layout) if sys.platform == "darwin": def set_open_file(state): if state: register_app_launchservices() else: restore_launchservices() macOS_group = QGroupBox(_("macOS integration")) mac_open_file_box = newcb( _("Open files from Finder with Spyder"), 'mac_open_file', tip=_("Register Spyder with the Launch Services")) mac_open_file_box.toggled.connect(set_open_file) macOS_layout = QVBoxLayout() macOS_layout.addWidget(mac_open_file_box) if als.get_bundle_identifier() is None: # Disable setting mac_open_file_box.setDisabled(True) macOS_layout.addWidget( QLabel( _('Launch Spyder with <code>python.app</code> to enable' ' Apple event integrations.'))) macOS_group.setLayout(macOS_layout) # --- Screen resolution Group (hidpi) screen_resolution_group = QGroupBox(_("Screen resolution")) screen_resolution_bg = QButtonGroup(screen_resolution_group) screen_resolution_label = QLabel( _("Configuration for high DPI " "screens<br><br>" "Please see " "<a href=\"{0}\">{0}</a><> " "for more information about " "these options (in " "English).").format(HDPI_QT_PAGE)) screen_resolution_label.setWordWrap(True) screen_resolution_label.setOpenExternalLinks(True) normal_radio = self.create_radiobutton( _("Normal"), 'normal_screen_resolution', button_group=screen_resolution_bg) auto_scale_radio = self.create_radiobutton( _("Enable auto high DPI scaling"), 'high_dpi_scaling', button_group=screen_resolution_bg, tip=_("Set this for high DPI displays"), restart=True) custom_scaling_radio = self.create_radiobutton( _("Set a custom high DPI scaling"), 'high_dpi_custom_scale_factor', button_group=screen_resolution_bg, tip=_("Set this for high DPI displays when " "auto scaling does not work"), restart=True) self.custom_scaling_edit = self.create_lineedit( "", 'high_dpi_custom_scale_factors', tip=_("Enter values for different screens " "separated by semicolons ';'.\n" "Float values are supported"), alignment=Qt.Horizontal, regex=r"[0-9]+(?:\.[0-9]*)(;[0-9]+(?:\.[0-9]*))*", restart=True) normal_radio.toggled.connect(self.custom_scaling_edit.setDisabled) auto_scale_radio.toggled.connect(self.custom_scaling_edit.setDisabled) custom_scaling_radio.toggled.connect( self.custom_scaling_edit.setEnabled) # Layout Screen resolution screen_resolution_layout = QVBoxLayout() screen_resolution_layout.addWidget(screen_resolution_label) screen_resolution_inner_layout = QGridLayout() screen_resolution_inner_layout.addWidget(normal_radio, 0, 0) screen_resolution_inner_layout.addWidget(auto_scale_radio, 1, 0) screen_resolution_inner_layout.addWidget(custom_scaling_radio, 2, 0) screen_resolution_inner_layout.addWidget(self.custom_scaling_edit, 2, 1) screen_resolution_layout.addLayout(screen_resolution_inner_layout) screen_resolution_group.setLayout(screen_resolution_layout) if sys.platform == "darwin": interface_tab = self.create_tab(screen_resolution_group, interface_group, macOS_group) else: interface_tab = self.create_tab(screen_resolution_group, interface_group) self.tabs = QTabWidget() self.tabs.addTab(interface_tab, _("Interface")) self.tabs.addTab(self.create_tab(advanced_widget), _("Advanced settings")) vlayout = QVBoxLayout() vlayout.addWidget(self.tabs) self.setLayout(vlayout)
class TourTestWindow(QMainWindow): """ """ sig_resized = Signal("QResizeEvent") sig_moved = Signal("QMoveEvent") def __init__(self): super(TourTestWindow, self).__init__() self.setGeometry(300, 100, 400, 600) self.setWindowTitle('Exploring QMainWindow') self.exit = QAction('Exit', self) self.exit.setStatusTip('Exit program') # create the menu bar menubar = self.menuBar() file_ = menubar.addMenu('&File') file_.addAction(self.exit) # create the status bar self.statusBar() # QWidget or its instance needed for box layout self.widget = QWidget(self) self.button = QPushButton('test') self.button1 = QPushButton('1') self.button2 = QPushButton('2') effect = QGraphicsOpacityEffect(self.button2) self.button2.setGraphicsEffect(effect) self.anim = QPropertyAnimation(effect, to_binary_string("opacity")) self.anim.setStartValue(0.01) self.anim.setEndValue(1.0) self.anim.setDuration(500) lay = QVBoxLayout() lay.addWidget(self.button) lay.addStretch() lay.addWidget(self.button1) lay.addWidget(self.button2) self.widget.setLayout(lay) self.setCentralWidget(self.widget) self.button.clicked.connect(self.action1) self.button1.clicked.connect(self.action2) self.tour = AnimatedTour(self) def action1(self): """ """ frames = get_tour('test') index = 0 dic = {'last': 0, 'tour': frames} self.tour.set_tour(index, dic, self) self.tour.start_tour() def action2(self): """ """ self.anim.start() def resizeEvent(self, event): """Reimplement Qt method""" QMainWindow.resizeEvent(self, event) self.sig_resized.emit(event) def moveEvent(self, event): """Reimplement Qt method""" QMainWindow.moveEvent(self, event) self.sig_moved.emit(event)
def on_activate(self): """ Activation method called on change to active state. This method creates the Manager main window. """ if _has_pyqtgraph: # set background of pyqtgraph testwidget = QWidget() testwidget.ensurePolished() bgcolor = testwidget.palette().color(QPalette.Normal, testwidget.backgroundRole()) # set manually the background color in hex code according to our # color scheme: pg.setConfigOption('background', bgcolor) # opengl usage if 'useOpenGL' in self._manager.tree['global']: pg.setConfigOption('useOpenGL', self._manager.tree['global']['useOpenGL']) self._mw = ManagerMainWindow() self.restoreWindowPos(self._mw) self.errorDialog = ErrorDialog(self) self._about = AboutDialog() version = self.getSoftwareVersion() configFile = self._manager.configFile self._about.label.setText( '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"' ' style=\"color: cyan;\"> {0} </a>, on branch {1}.'.format( version[0], version[1])) self.versionLabel = QtWidgets.QLabel() self.versionLabel.setText( '<a href=\"https://github.com/Ulm-IQO/qudi/commit/{0}\"' ' style=\"color: cyan;\"> {0} </a>,' ' on branch {1}, configured from {2}'.format( version[0], version[1], configFile)) self.versionLabel.setOpenExternalLinks(True) self._mw.statusBar().addWidget(self.versionLabel) # Connect up the buttons. self._mw.actionQuit.triggered.connect(self._manager.quit) self._mw.actionLoad_configuration.triggered.connect(self.getLoadFile) self._mw.actionReload_current_configuration.triggered.connect( self.reloadConfig) self._mw.actionSave_configuration.triggered.connect(self.getSaveFile) self._mw.action_Load_all_modules.triggered.connect( self._manager.startAllConfiguredModules) self._mw.actionAbout_Qt.triggered.connect( QtWidgets.QApplication.aboutQt) self._mw.actionAbout_Qudi.triggered.connect(self.showAboutQudi) self._mw.actionReset_to_default_layout.triggered.connect( self.resetToDefaultLayout) self._manager.sigShowManager.connect(self.show) self._manager.sigConfigChanged.connect(self.updateConfigWidgets) self._manager.sigModulesChanged.connect(self.updateConfigWidgets) self._manager.sigShutdownAcknowledge.connect(self.promptForShutdown) # Log widget self._mw.logwidget.setManager(self._manager) for loghandler in logging.getLogger().handlers: if isinstance(loghandler, core.logger.QtLogHandler): loghandler.sigLoggedMessage.connect(self.handleLogEntry) # Module widgets self.sigStartModule.connect(self._manager.startModule) self.sigReloadModule.connect(self._manager.restartModuleRecursive) self.sigCleanupStatus.connect(self._manager.removeStatusFile) self.sigStopModule.connect(self._manager.deactivateModule) self.sigLoadConfig.connect(self._manager.loadConfig) self.sigSaveConfig.connect(self._manager.saveConfig) self.sigRealQuit.connect(self._manager.realQuit) # Module state display self.checkTimer = QtCore.QTimer() self.checkTimer.start(1000) self.updateGUIModuleList() # IPython console widget self.startIPython() self.updateIPythonModuleList() self.startIPythonWidget() # thread widget self._mw.threadWidget.threadListView.setModel(self._manager.tm) # remote widget # hide remote menu item if rpyc is not available self._mw.actionRemoteView.setVisible(self._manager.rm is not None) if self._manager.rm is not None: self._mw.remoteWidget.remoteModuleListView.setModel( self._manager.rm.remoteModules) if self._manager.remote_server: self._mw.remoteWidget.hostLabel.setText('Server URL:') self._mw.remoteWidget.portLabel.setText( 'rpyc://{0}:{1}/'.format(self._manager.rm.server.host, self._manager.rm.server.port)) self._mw.remoteWidget.sharedModuleListView.setModel( self._manager.rm.sharedModules) else: self._mw.remoteWidget.hostLabel.setVisible(False) self._mw.remoteWidget.portLabel.setVisible(False) self._mw.remoteWidget.sharedModuleListView.setVisible(False) self._mw.configDisplayDockWidget.hide() self._mw.remoteDockWidget.hide() self._mw.threadDockWidget.hide() self._mw.show()
def __init__(self, parent, enable_replace=False): QWidget.__init__(self, parent) self.enable_replace = enable_replace self.editor = None self.is_code_editor = None glayout = QGridLayout() glayout.setContentsMargins(0, 0, 0, 0) self.setLayout(glayout) self.close_button = create_toolbutton( self, triggered=self.hide, icon=ima.icon('DialogCloseButton')) glayout.addWidget(self.close_button, 0, 0) # Find layout self.search_text = PatternComboBox(self, tip=_("Search string"), adjust_to_minimum=False) self.return_shift_pressed.connect( lambda: self.find(changed=False, forward=False, rehighlight=False, multiline_replace_check=False)) self.return_pressed.connect( lambda: self.find(changed=False, forward=True, rehighlight=False, multiline_replace_check=False)) self.search_text.lineEdit().textEdited.connect( self.text_has_been_edited) self.number_matches_text = QLabel(self) self.previous_button = create_toolbutton(self, triggered=self.find_previous, icon=ima.icon('ArrowUp')) self.next_button = create_toolbutton(self, triggered=self.find_next, icon=ima.icon('ArrowDown')) self.next_button.clicked.connect(self.update_search_combo) self.previous_button.clicked.connect(self.update_search_combo) self.re_button = create_toolbutton(self, icon=ima.icon('advanced'), tip=_("Regular expression")) self.re_button.setCheckable(True) self.re_button.toggled.connect(lambda state: self.find()) self.case_button = create_toolbutton(self, icon=get_icon("upper_lower.png"), tip=_("Case Sensitive")) self.case_button.setCheckable(True) self.case_button.toggled.connect(lambda state: self.find()) self.words_button = create_toolbutton(self, icon=get_icon("whole_words.png"), tip=_("Whole words")) self.words_button.setCheckable(True) self.words_button.toggled.connect(lambda state: self.find()) self.highlight_button = create_toolbutton( self, icon=get_icon("highlight.png"), tip=_("Highlight matches")) self.highlight_button.setCheckable(True) self.highlight_button.toggled.connect(self.toggle_highlighting) hlayout = QHBoxLayout() self.widgets = [ self.close_button, self.search_text, self.number_matches_text, self.previous_button, self.next_button, self.re_button, self.case_button, self.words_button, self.highlight_button ] for widget in self.widgets[1:]: hlayout.addWidget(widget) glayout.addLayout(hlayout, 0, 1) # Replace layout replace_with = QLabel(_("Replace with:")) self.replace_text = PatternComboBox(self, adjust_to_minimum=False, tip=_('Replace string')) self.replace_text.valid.connect( lambda _: self.replace_find(focus_replace_text=True)) self.replace_button = create_toolbutton( self, text=_('Replace/find next'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find, text_beside_icon=True) self.replace_sel_button = create_toolbutton( self, text=_('Replace selection'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find_selection, text_beside_icon=True) self.replace_sel_button.clicked.connect(self.update_replace_combo) self.replace_sel_button.clicked.connect(self.update_search_combo) self.replace_all_button = create_toolbutton( self, text=_('Replace all'), icon=ima.icon('DialogApplyButton'), triggered=self.replace_find_all, text_beside_icon=True) self.replace_all_button.clicked.connect(self.update_replace_combo) self.replace_all_button.clicked.connect(self.update_search_combo) self.replace_layout = QHBoxLayout() widgets = [ replace_with, self.replace_text, self.replace_button, self.replace_sel_button, self.replace_all_button ] for widget in widgets: self.replace_layout.addWidget(widget) glayout.addLayout(self.replace_layout, 1, 1) self.widgets.extend(widgets) self.replace_widgets = widgets self.hide_replace() self.search_text.setTabOrder(self.search_text, self.replace_text) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.shortcuts = self.create_shortcuts(parent) self.highlight_timer = QTimer(self) self.highlight_timer.setSingleShot(True) self.highlight_timer.setInterval(1000) self.highlight_timer.timeout.connect(self.highlight_matches) self.search_text.installEventFilter(self)
def __init__(self, viewer): super().__init__() QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtControls(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self.console = QtConsole({'viewer': self.viewer}) # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} if self.console.shell is not None: self.console.style().unpolish(self.console) self.console.style().polish(self.console) self.console.hide() self.viewerButtons.consoleButton.clicked.connect( lambda: self._toggle_console()) else: self.viewerButtons.consoleButton.setEnabled(False) self.canvas = SceneCanvas(keys=None, vsync=True) self.canvas.events.ignore_callback_errors = False self.canvas.native.setMinimumSize(QSize(200, 200)) self.canvas.context.set_depth_func('lequal') self.canvas.connect(self.on_mouse_move) self.canvas.connect(self.on_mouse_press) self.canvas.connect(self.on_mouse_release) self.canvas.connect(self.on_key_press) self.canvas.connect(self.on_key_release) self.canvas.connect(self.on_draw) self.view = self.canvas.central_widget.add_view() self._update_camera() main_widget = QWidget() main_layout = QGridLayout() main_layout.setContentsMargins(15, 20, 15, 10) main_layout.addWidget(self.canvas.native, 0, 1, 3, 1) main_layout.addWidget(self.dims, 3, 1) main_layout.addWidget(self.controls, 0, 0) main_layout.addWidget(self.layerButtons, 1, 0) main_layout.addWidget(self.layers, 2, 0) main_layout.addWidget(self.viewerButtons, 3, 0) main_layout.setColumnStretch(1, 1) main_layout.setSpacing(10) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) if self.console.shell is not None: self.addWidget(self.console) self._last_visited_dir = str(Path.home()) self._cursors = { 'disabled': QCursor( QPixmap(':/icons/cursor/cursor_disabled.png').scaled(20, 20)), 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._update_palette(viewer.palette) self._key_release_generators = {} self.viewer.events.interactive.connect(self._on_interactive) self.viewer.events.cursor.connect(self._on_cursor) self.viewer.events.reset_view.connect(self._on_reset_view) self.viewer.events.palette.connect( lambda event: self._update_palette(event.palette)) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.added.connect(self._add_layer) self.viewer.layers.events.removed.connect(self._remove_layer) self.viewer.dims.events.camera.connect( lambda event: self._update_camera()) self.setAcceptDrops(True)
def setup_toolbar(self): """Setup the toolbar""" savefig_btn = create_toolbutton(self, icon=ima.icon('filesave'), tip=_("Save Image As..."), triggered=self.save_figure) saveall_btn = create_toolbutton(self, icon=ima.icon('save_all'), tip=_("Save All Images..."), triggered=self.save_all_figures) copyfig_btn = create_toolbutton( self, icon=ima.icon('editcopy'), tip=(_("Copy plot to clipboard as image (%s)") % CONF.get_shortcut('plots', 'copy')), triggered=self.copy_figure) closefig_btn = create_toolbutton(self, icon=ima.icon('editclear'), tip=_("Remove image"), triggered=self.close_figure) closeall_btn = create_toolbutton( self, icon=ima.icon('filecloseall'), tip=_("Remove all images from the explorer"), triggered=self.close_all_figures) vsep1 = QFrame() vsep1.setFrameStyle(53) goback_btn = create_toolbutton(self, icon=ima.icon('ArrowBack'), tip=_("Previous figure ({})").format( CONF.get_shortcut( 'plots', 'previous figure')), triggered=self.go_previous_thumbnail) gonext_btn = create_toolbutton(self, icon=ima.icon('ArrowForward'), tip=_("Next figure ({})").format( CONF.get_shortcut( 'plots', 'next figure')), triggered=self.go_next_thumbnail) vsep2 = QFrame() vsep2.setFrameStyle(53) self.zoom_out_btn = create_toolbutton( self, icon=ima.icon('zoom_out'), tip=_("Zoom out (Ctrl + mouse-wheel-down)"), triggered=self.zoom_out) self.zoom_in_btn = create_toolbutton( self, icon=ima.icon('zoom_in'), tip=_("Zoom in (Ctrl + mouse-wheel-up)"), triggered=self.zoom_in) self.zoom_disp = QSpinBox() self.zoom_disp.setAlignment(Qt.AlignCenter) self.zoom_disp.setButtonSymbols(QSpinBox.NoButtons) self.zoom_disp.setReadOnly(True) self.zoom_disp.setSuffix(' %') self.zoom_disp.setRange(0, 9999) self.zoom_disp.setValue(100) self.figviewer.sig_zoom_changed.connect(self.zoom_disp.setValue) zoom_pan = QWidget() layout = QHBoxLayout(zoom_pan) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.zoom_out_btn) layout.addWidget(self.zoom_in_btn) layout.addWidget(self.zoom_disp) return [ savefig_btn, saveall_btn, copyfig_btn, closefig_btn, closeall_btn, vsep1, goback_btn, gonext_btn, vsep2, zoom_pan ]
def __init__(self, config_file, run_model, simulation_arguments, parent=None): QDialog.__init__(self, parent) self.setWindowFlags(Qt.Window) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.setModal(True) self.setWindowModality(Qt.WindowModal) self.setWindowTitle("Simulations - {}".format(config_file)) self._snapshot_model = SnapshotModel(self) self._run_model = run_model self._isDetailedDialog = False self._minimum_width = 1200 ert = None if isinstance(run_model, BaseRunModel): ert = run_model.ert() self._simulations_argments = simulation_arguments self._ticker = QTimer(self) self._ticker.timeout.connect(self._on_ticker) progress_proxy_model = ProgressProxyModel(self._snapshot_model, parent=self) self._total_progress_label = QLabel( _TOTAL_PROGRESS_TEMPLATE.format( total_progress=0, phase_name=run_model.getPhaseName() ), self, ) self._total_progress_bar = QProgressBar(self) self._total_progress_bar.setRange(0, 100) self._total_progress_bar.setTextVisible(False) self._iteration_progress_label = QLabel(self) self._progress_view = ProgressView(self) self._progress_view.setModel(progress_proxy_model) self._progress_view.setIndeterminate(True) legend_view = LegendView(self) legend_view.setModel(progress_proxy_model) self._tab_widget = QTabWidget(self) self._snapshot_model.rowsInserted.connect(self.on_new_iteration) self._job_label = QLabel(self) self._job_model = JobListProxyModel(self, 0, 0, 0, 0) self._job_model.setSourceModel(self._snapshot_model) self._job_view = QTableView(self) self._job_view.clicked.connect(self._job_clicked) self._open_files = {} self._job_view.setModel(self._job_model) self.running_time = QLabel("") self.plot_tool = PlotTool(config_file) self.plot_tool.setParent(self) self.plot_button = QPushButton(self.plot_tool.getName()) self.plot_button.clicked.connect(self.plot_tool.trigger) self.plot_button.setEnabled(ert is not None) self.kill_button = QPushButton("Kill Simulations") self.done_button = QPushButton("Done") self.done_button.setHidden(True) self.restart_button = QPushButton("Restart") self.restart_button.setHidden(True) self.show_details_button = QPushButton("Show Details") self.show_details_button.setCheckable(True) size = 20 spin_movie = resourceMovie("ide/loading.gif") spin_movie.setSpeed(60) spin_movie.setScaledSize(QSize(size, size)) spin_movie.start() self.processing_animation = QLabel() self.processing_animation.setMaximumSize(QSize(size, size)) self.processing_animation.setMinimumSize(QSize(size, size)) self.processing_animation.setMovie(spin_movie) button_layout = QHBoxLayout() button_layout.addWidget(self.processing_animation) button_layout.addWidget(self.running_time) button_layout.addStretch() button_layout.addWidget(self.show_details_button) button_layout.addWidget(self.plot_button) button_layout.addWidget(self.kill_button) button_layout.addWidget(self.done_button) button_layout.addWidget(self.restart_button) button_widget_container = QWidget() button_widget_container.setLayout(button_layout) layout = QVBoxLayout() layout.addWidget(self._total_progress_label) layout.addWidget(self._total_progress_bar) layout.addWidget(self._iteration_progress_label) layout.addWidget(self._progress_view) layout.addWidget(legend_view) layout.addWidget(self._tab_widget) layout.addWidget(self._job_label) layout.addWidget(self._job_view) layout.addWidget(button_widget_container) self.setLayout(layout) self.kill_button.clicked.connect(self.killJobs) self.done_button.clicked.connect(self.accept) self.restart_button.clicked.connect(self.restart_failed_realizations) self.show_details_button.clicked.connect(self.toggle_detailed_progress) self.simulation_done.connect(self._on_simulation_done) self.setMinimumWidth(self._minimum_width) self._setSimpleDialog()
def setup_options_actions(self, parent): """ Setup the actions for the Options menu. The actions are handled by the parent widget """ container_widget = QWidget(self) layout = QHBoxLayout(container_widget) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) container_widget.setLayout(layout) self.setCornerWidget(container_widget, Qt.TopRightCorner) run_button = QPushButton(container_widget) run_button.setObjectName(self.RUN_BUTTON_OBJECT_NAME) run_button.setIcon(get_icon("mdi.play", PLAY_BUTTON_GREEN_COLOR, 1.6)) run_button.clicked.connect(parent.execute_current_async) layout.addWidget(run_button) abort_button = QPushButton(container_widget) abort_button.setObjectName(self.ABORT_BUTTON_OBJECT_NAME) abort_button.setIcon( get_icon("mdi.square", ABORT_BUTTON_RED_COLOR, 1.1)) abort_button.clicked.connect(parent.abort_current) layout.addWidget(abort_button) options_button = QPushButton(container_widget) options_button.setObjectName(self.OPTIONS_BUTTON_OBJECT_NAME) options_button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) options_button.setText("Options") options_menu = QMenu("", self) options_button.setMenu(options_menu) layout.addWidget(options_button) self.tabCloseRequested.connect(parent.close_tab) run_action = create_action(self, "Run", on_triggered=parent.execute_current_async, shortcut=("Ctrl+Enter", "Ctrl+Return"), shortcut_context=Qt.ApplicationShortcut, shortcut_visible_in_context_menu=True) run_all_action = create_action(self, "Run All", on_triggered=parent.execute_async, shortcut=("Ctrl+Shift+Enter", "Ctrl+Shift+Return"), shortcut_context=Qt.ApplicationShortcut, shortcut_visible_in_context_menu=True) abort_action = create_action(self, "Abort", on_triggered=parent.abort_current) # menu action to toggle the find/replace dialog toggle_find_replace = create_action( self, 'Find/Replace...', on_triggered=parent.toggle_find_replace_dialog, shortcut='Ctrl+F', shortcut_visible_in_context_menu=True) toggle_comment_action = create_action( self, "Comment/Uncomment", on_triggered=parent.toggle_comment_current, shortcut="Ctrl+/", shortcut_context=Qt.ApplicationShortcut, shortcut_visible_in_context_menu=True) tabs_to_spaces_action = create_action( self, 'Tabs to Spaces', on_triggered=parent.tabs_to_spaces_current, shortcut_visible_in_context_menu=True) spaces_to_tabs_action = create_action( self, 'Spaces to Tabs', on_triggered=parent.spaces_to_tabs_current, shortcut_visible_in_context_menu=True) toggle_whitespace_action = create_action( self, 'Toggle Whitespace Visible', on_triggered=parent.toggle_whitespace_visible_all, shortcut_visible_in_context_menu=True) # Store actions for adding to menu bar; None will add a separator editor_actions = [ run_action, run_all_action, abort_action, None, toggle_find_replace, None, toggle_comment_action, toggle_whitespace_action, None, tabs_to_spaces_action, spaces_to_tabs_action ] add_actions(options_menu, editor_actions)
def __init__(self, parent, required_packages: [str]): super(SelectPackages_Dialog, self).__init__(parent) self.file_paths = [] self.required_packages: [str] = required_packages self.packages = [] self.setLayout(QVBoxLayout()) self.layout().addWidget( QLabel( 'You need to select the locations of the following required node packages' )) # package lists required_packages_list_widget = QListWidget() for p_name in required_packages: required_packages_list_widget.addItem(QListWidgetItem(p_name)) selected_items_widget = QWidget() selected_items_widget.setLayout(QVBoxLayout()) self.selected_packages_list_widget = QListWidget() selected_items_widget.layout().addWidget( self.selected_packages_list_widget) auto_import_button = QPushButton('auto import') auto_import_button.setFocus() auto_import_button.clicked.connect(self.auto_import_button_clicked) selected_items_widget.layout().addWidget(auto_import_button) add_package_button = QPushButton('add') add_package_button.clicked.connect(self.add_package_button_clicked) selected_items_widget.layout().addWidget(add_package_button) clear_package_list_button = QPushButton('clear') clear_package_list_button.clicked.connect( self.clear_selected_packages_list) selected_items_widget.layout().addWidget(clear_package_list_button) finished_button = QPushButton('OK') finished_button.clicked.connect(self.finished_button_clicked) selected_items_widget.layout().addWidget(finished_button) packages_lists_widget = QWidget() packages_lists_widget.setLayout(QHBoxLayout()) packages_lists_widget.layout().addWidget(required_packages_list_widget) packages_lists_widget.layout().addWidget(selected_items_widget) self.layout().addWidget(packages_lists_widget) self.setWindowTitle('select required packages')
def my_function(_): sum = 0 for i in range(10): sum += i sleep(0.1) return sum button_layout = QVBoxLayout() start_btn = QPushButton("Start") start_btn.clicked.connect(my_long_running_thread) button_layout.addWidget(start_btn) start_btn2 = QPushButton("Start Indeterminate") start_btn2.clicked.connect(my_indeterminate_thread) button_layout.addWidget(start_btn2) start_btn3 = QPushButton("Start FunctionWorker") start_btn3.clicked.connect(my_function) button_layout.addWidget(start_btn3) pbar_widget = QWidget() pbar_widget.setLayout(button_layout) pbar_widget.setObjectName("Threading Examples") viewer.window.add_dock_widget(pbar_widget, allowed_areas=["right"]) # showing the activity dock so we can see the progress bars viewer.window._toggle_activity_dock(True) napari.run()
def createSpace(size=5): """Creates a widget that can be used as spacing on a panel.""" qw = QWidget() qw.setMinimumSize(QSize(size, size)) return qw
def __init__(self, parent): super(KiteInstallation, self).__init__(parent) # Left side action_layout = QVBoxLayout() progress_layout = QHBoxLayout() self._progress_widget = QWidget(self) self._progress_widget.setFixedHeight(50) self._progress_filter = HoverEventFilter() self._progress_bar = QProgressBar(self) self._progress_bar.setFixedWidth(180) self._progress_widget.installEventFilter(self._progress_filter) self.cancel_button = QPushButton() self.cancel_button.setIcon(ima.icon('DialogCloseButton')) self.cancel_button.hide() progress_layout.addWidget(self._progress_bar, alignment=Qt.AlignLeft) progress_layout.addWidget(self.cancel_button) self._progress_widget.setLayout(progress_layout) self._progress_label = QLabel(_('Downloading')) install_info = QLabel( _("Kite comes with a native app called the Copilot <br>" "which provides you with real time <br>" "documentation as you code.<br><br>" "When Kite is done installing, the Copilot will <br>" "launch automatically and guide you throught the <br>" "rest of the setup process.")) button_layout = QHBoxLayout() self.ok_button = QPushButton(_('OK')) button_layout.addStretch() button_layout.addWidget(self.ok_button) button_layout.addStretch() action_layout.addStretch() action_layout.addWidget(self._progress_label) action_layout.addWidget(self._progress_widget) action_layout.addWidget(install_info) action_layout.addSpacing(10) action_layout.addLayout(button_layout) action_layout.addStretch() # Right side copilot_image_source = get_image_path('kite_copilot.png') copilot_image = QPixmap(copilot_image_source) copilot_label = QLabel() screen = QApplication.primaryScreen() device_pixel_ratio = screen.devicePixelRatio() if device_pixel_ratio > 1: copilot_image.setDevicePixelRatio(device_pixel_ratio) copilot_label.setPixmap(copilot_image) else: image_height = copilot_image.height() * 0.4 image_width = copilot_image.width() * 0.4 copilot_label.setPixmap( copilot_image.scaled(image_width, image_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)) # Layout general_layout = QHBoxLayout() general_layout.addLayout(action_layout) general_layout.addWidget(copilot_label) self.setLayout(general_layout) # Signals self._progress_filter.sig_hover_enter.connect( lambda: self.cancel_button.show()) self._progress_filter.sig_hover_leave.connect( lambda: self.cancel_button.hide())
class ThumbnailScrollBar(QFrame): """ A widget that manages the display of the FigureThumbnails that are created when a figure is sent to the IPython console by the kernel and that controls what is displayed in the FigureViewer. """ redirect_stdio = Signal(bool) _min_scrollbar_width = 100 def __init__(self, figure_viewer, parent=None, background_color=None): super(ThumbnailScrollBar, self).__init__(parent) self._thumbnails = [] self.background_color = background_color self.current_thumbnail = None self.set_figureviewer(figure_viewer) self.setup_gui() def setup_gui(self): """Setup the main layout of the widget.""" scrollarea = self.setup_scrollarea() up_btn, down_btn = self.setup_arrow_buttons() layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(up_btn) layout.addWidget(scrollarea) layout.addWidget(down_btn) def setup_scrollarea(self): """Setup the scrollarea that will contain the FigureThumbnails.""" self.view = QWidget() self.scene = QGridLayout(self.view) self.scene.setContentsMargins(0, 0, 0, 0) self.scrollarea = QScrollArea() self.scrollarea.setWidget(self.view) self.scrollarea.setWidgetResizable(True) self.scrollarea.setFrameStyle(0) self.scrollarea.setViewportMargins(2, 2, 2, 2) self.scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollarea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.scrollarea.setMinimumWidth(self._min_scrollbar_width) # Set the vertical scrollbar explicitely. # This is required to avoid a "RuntimeError: no access to protected # functions or signals for objects not created from Python" in Linux. self.scrollarea.setVerticalScrollBar(QScrollBar()) # Install an event filter on the scrollbar. self.scrollarea.installEventFilter(self) return self.scrollarea def setup_arrow_buttons(self): """ Setup the up and down arrow buttons that are placed at the top and bottom of the scrollarea. """ # Get the size hint height of the horizontal scrollbar. height = self.scrollarea.horizontalScrollBar().sizeHint().height() # Setup the up and down arrow button. up_btn = up_btn = QPushButton(icon=ima.icon('last_edit_location')) up_btn.setFlat(True) up_btn.setFixedHeight(height) up_btn.clicked.connect(self.go_up) down_btn = QPushButton(icon=ima.icon('folding.arrow_down_on')) down_btn.setFlat(True) down_btn.setFixedHeight(height) down_btn.clicked.connect(self.go_down) return up_btn, down_btn def set_figureviewer(self, figure_viewer): """Set the bamespace for the FigureViewer.""" self.figure_viewer = figure_viewer def eventFilter(self, widget, event): """ An event filter to trigger an update of the thumbnails size so that their width fit that of the scrollarea. """ if event.type() == QEvent.Resize: self._update_thumbnail_size() return super(ThumbnailScrollBar, self).eventFilter(widget, event) # ---- Save Figure def save_all_figures_as(self): """Save all the figures to a file.""" self.redirect_stdio.emit(False) dirname = getexistingdirectory(self, caption='Save all figures', basedir=getcwd_or_home()) self.redirect_stdio.emit(True) if dirname: return self.save_all_figures_todir(dirname) def save_all_figures_todir(self, dirname): """Save all figure in dirname.""" fignames = [] for thumbnail in self._thumbnails: fig = thumbnail.canvas.fig fmt = thumbnail.canvas.fmt fext = { 'image/png': '.png', 'image/jpeg': '.jpg', 'image/svg+xml': '.svg' }[fmt] figname = get_unique_figname(dirname, 'Figure', fext) save_figure_tofile(fig, fmt, figname) fignames.append(figname) return fignames def save_current_figure_as(self): """Save the currently selected figure.""" if self.current_thumbnail is not None: self.save_figure_as(self.current_thumbnail.canvas.fig, self.current_thumbnail.canvas.fmt) def save_figure_as(self, fig, fmt): """Save the figure to a file.""" fext, ffilt = { 'image/png': ('.png', 'PNG (*.png)'), 'image/jpeg': ('.jpg', 'JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)'), 'image/svg+xml': ('.svg', 'SVG (*.svg);;PNG (*.png)') }[fmt] figname = get_unique_figname(getcwd_or_home(), 'Figure', fext) self.redirect_stdio.emit(False) fname, fext = getsavefilename(parent=self.parent(), caption='Save Figure', basedir=figname, filters=ffilt, selectedfilter='', options=None) self.redirect_stdio.emit(True) if fname: save_figure_tofile(fig, fmt, fname) # ---- Thumbails Handlers def _calculate_figure_canvas_width(self, thumbnail): """ Calculate the witdh the thumbnail's figure canvas need to have for the thumbnail to fit the scrollarea. """ extra_padding = 10 if sys.platform == 'darwin' else 0 figure_canvas_width = (self.scrollarea.width() - 2 * self.lineWidth() - self.scrollarea.viewportMargins().left() - self.scrollarea.viewportMargins().right() - thumbnail.savefig_btn.width() - thumbnail.layout().spacing() - extra_padding) if is_dark_interface(): # This is required to take into account some hard-coded padding # and margin in qdarkstyle. figure_canvas_width = figure_canvas_width - 6 return figure_canvas_width def _setup_thumbnail_size(self, thumbnail): """ Scale the thumbnail's canvas size so that it fits the thumbnail scrollbar's width. """ max_canvas_size = self._calculate_figure_canvas_width(thumbnail) thumbnail.scale_canvas_size(max_canvas_size) def _update_thumbnail_size(self): """ Update the thumbnails size so that their width fit that of the scrollarea. """ # NOTE: We hide temporarily the thumbnails to prevent a repaint of # each thumbnail as soon as their size is updated in the loop, which # causes some flickering of the thumbnail scrollbar resizing animation. # Once the size of all the thumbnails has been updated, we show them # back so that they are repainted all at once instead of one after the # other. This is just a trick to make the resizing animation of the # thumbnail scrollbar look smoother. self.view.hide() for thumbnail in self._thumbnails: self._setup_thumbnail_size(thumbnail) self.view.show() def add_thumbnail(self, fig, fmt): """ Add a new thumbnail to that thumbnail scrollbar. """ thumbnail = FigureThumbnail(parent=self, background_color=self.background_color) thumbnail.canvas.load_figure(fig, fmt) thumbnail.sig_canvas_clicked.connect(self.set_current_thumbnail) thumbnail.sig_remove_figure.connect(self.remove_thumbnail) thumbnail.sig_save_figure.connect(self.save_figure_as) self._thumbnails.append(thumbnail) self.scene.setRowStretch(self.scene.rowCount() - 1, 0) self.scene.addWidget(thumbnail, self.scene.rowCount() - 1, 0) self.scene.setRowStretch(self.scene.rowCount(), 100) self.set_current_thumbnail(thumbnail) thumbnail.show() self._setup_thumbnail_size(thumbnail) def remove_current_thumbnail(self): """Remove the currently selected thumbnail.""" if self.current_thumbnail is not None: self.remove_thumbnail(self.current_thumbnail) def remove_all_thumbnails(self): """Remove all thumbnails.""" for thumbnail in self._thumbnails: self.layout().removeWidget(thumbnail) thumbnail.sig_canvas_clicked.disconnect() thumbnail.sig_remove_figure.disconnect() thumbnail.sig_save_figure.disconnect() thumbnail.setParent(None) self._thumbnails = [] self.current_thumbnail = None self.figure_viewer.figcanvas.clear_canvas() def remove_thumbnail(self, thumbnail): """Remove thumbnail.""" if thumbnail in self._thumbnails: index = self._thumbnails.index(thumbnail) self._thumbnails.remove(thumbnail) self.layout().removeWidget(thumbnail) thumbnail.setParent(None) thumbnail.sig_canvas_clicked.disconnect() thumbnail.sig_remove_figure.disconnect() thumbnail.sig_save_figure.disconnect() # Select a new thumbnail if any : if thumbnail == self.current_thumbnail: if len(self._thumbnails) > 0: self.set_current_index(min(index, len(self._thumbnails) - 1)) else: self.current_thumbnail = None self.figure_viewer.figcanvas.clear_canvas() def set_current_index(self, index): """Set the currently selected thumbnail by its index.""" self.set_current_thumbnail(self._thumbnails[index]) def get_current_index(self): """Return the index of the currently selected thumbnail.""" try: return self._thumbnails.index(self.current_thumbnail) except ValueError: return -1 def set_current_thumbnail(self, thumbnail): """Set the currently selected thumbnail.""" self.current_thumbnail = thumbnail self.figure_viewer.load_figure(thumbnail.canvas.fig, thumbnail.canvas.fmt) for thumbnail in self._thumbnails: thumbnail.highlight_canvas(thumbnail == self.current_thumbnail) def go_previous_thumbnail(self): """Select the thumbnail previous to the currently selected one.""" if self.current_thumbnail is not None: index = self._thumbnails.index(self.current_thumbnail) - 1 index = index if index >= 0 else len(self._thumbnails) - 1 self.set_current_index(index) self.scroll_to_item(index) def go_next_thumbnail(self): """Select thumbnail next to the currently selected one.""" if self.current_thumbnail is not None: index = self._thumbnails.index(self.current_thumbnail) + 1 index = 0 if index >= len(self._thumbnails) else index self.set_current_index(index) self.scroll_to_item(index) def scroll_to_item(self, index): """Scroll to the selected item of ThumbnailScrollBar.""" spacing_between_items = self.scene.verticalSpacing() height_view = self.scrollarea.viewport().height() height_item = self.scene.itemAt(index).sizeHint().height() height_view_excluding_item = max(0, height_view - height_item) height_of_top_items = spacing_between_items for i in range(index): item = self.scene.itemAt(i) height_of_top_items += item.sizeHint().height() height_of_top_items += spacing_between_items pos_scroll = height_of_top_items - height_view_excluding_item // 2 vsb = self.scrollarea.verticalScrollBar() vsb.setValue(pos_scroll) # ---- ScrollBar Handlers def go_up(self): """Scroll the scrollbar of the scrollarea up by a single step.""" vsb = self.scrollarea.verticalScrollBar() vsb.setValue(int(vsb.value() - vsb.singleStep())) def go_down(self): """Scroll the scrollbar of the scrollarea down by a single step.""" vsb = self.scrollarea.verticalScrollBar() vsb.setValue(int(vsb.value() + vsb.singleStep()))
def setup_ui(self): self.resize(1080, 640) vlay_1 = QVBoxLayout(self) self.h_splitter = QSplitter(self) vlay_1.addWidget(self.h_splitter) self.h_splitter.setOrientation(Qt.Horizontal) self.v_splitter = QSplitter(self.h_splitter) self.v_splitter.setOrientation(Qt.Vertical) self.v_splitter.setMinimumWidth(500) self.plugin_sorter = QtPluginSorter(parent=self.h_splitter) self.plugin_sorter.layout().setContentsMargins(2, 0, 0, 0) self.plugin_sorter.hide() installed = QWidget(self.v_splitter) lay = QVBoxLayout(installed) lay.setContentsMargins(0, 2, 0, 2) self.installed_label = QLabel(trans._("Installed Plugins")) self.installed_filter = QLineEdit() self.installed_filter.setPlaceholderText("search...") self.installed_filter.setMaximumWidth(350) self.installed_filter.setClearButtonEnabled(True) mid_layout = QHBoxLayout() mid_layout.addWidget(self.installed_label) mid_layout.addWidget(self.installed_filter) mid_layout.addStretch() lay.addLayout(mid_layout) self.installed_list = QPluginList(installed, self.installer) self.installed_filter.textChanged.connect(self.installed_list.filter) lay.addWidget(self.installed_list) uninstalled = QWidget(self.v_splitter) lay = QVBoxLayout(uninstalled) lay.setContentsMargins(0, 2, 0, 2) self.avail_label = QLabel(trans._("Available Plugins")) self.avail_filter = QLineEdit() self.avail_filter.setPlaceholderText("search...") self.avail_filter.setMaximumWidth(350) self.avail_filter.setClearButtonEnabled(True) mid_layout = QHBoxLayout() mid_layout.addWidget(self.avail_label) mid_layout.addWidget(self.avail_filter) mid_layout.addStretch() lay.addLayout(mid_layout) self.available_list = QPluginList(uninstalled, self.installer) self.avail_filter.textChanged.connect(self.available_list.filter) lay.addWidget(self.available_list) self.stdout_text = QTextEdit(self.v_splitter) self.stdout_text.setReadOnly(True) self.stdout_text.setObjectName("pip_install_status") self.stdout_text.hide() buttonBox = QHBoxLayout() self.working_indicator = QLabel(trans._("loading ..."), self) sp = self.working_indicator.sizePolicy() sp.setRetainSizeWhenHidden(True) self.working_indicator.setSizePolicy(sp) self.process_error_indicator = QLabel(self) self.process_error_indicator.setObjectName("error_label") self.process_error_indicator.hide() load_gif = str(Path(napari.resources.__file__).parent / "loading.gif") mov = QMovie(load_gif) mov.setScaledSize(QSize(18, 18)) self.working_indicator.setMovie(mov) mov.start() self.direct_entry_edit = QLineEdit(self) self.direct_entry_edit.installEventFilter(self) self.direct_entry_edit.setPlaceholderText( trans._('install by name/url, or drop file...')) self.direct_entry_btn = QPushButton(trans._("Install"), self) self.direct_entry_btn.clicked.connect(self._install_packages) self.show_status_btn = QPushButton(trans._("Show Status"), self) self.show_status_btn.setFixedWidth(100) self.show_sorter_btn = QPushButton(trans._("<< Show Sorter"), self) self.close_btn = QPushButton(trans._("Close"), self) self.close_btn.clicked.connect(self.accept) buttonBox.addWidget(self.show_status_btn) buttonBox.addWidget(self.working_indicator) buttonBox.addWidget(self.direct_entry_edit) buttonBox.addWidget(self.direct_entry_btn) buttonBox.addWidget(self.process_error_indicator) buttonBox.addSpacing(60) buttonBox.addWidget(self.show_sorter_btn) buttonBox.addWidget(self.close_btn) buttonBox.setContentsMargins(0, 0, 4, 0) vlay_1.addLayout(buttonBox) self.show_status_btn.setCheckable(True) self.show_status_btn.setChecked(False) self.show_status_btn.toggled.connect(self._toggle_status) self.show_sorter_btn.setCheckable(True) self.show_sorter_btn.setChecked(False) self.show_sorter_btn.toggled.connect(self._toggle_sorter) self.v_splitter.setStretchFactor(1, 2) self.h_splitter.setStretchFactor(0, 2) self.avail_filter.setFocus()
def __init__(self, parent, max_entries=100, options_button=None, text_color=None): QWidget.__init__(self, parent) self.setWindowTitle("Profiler") self.output = None self.error_output = None self.text_color = text_color self._last_wdir = None self._last_args = None self._last_pythonpath = None self.filecombo = PythonModulesComboBox(self) self.start_button = create_toolbutton(self, icon=ima.icon('run'), text=_("Profile"), tip=_("Run profiler"), triggered=lambda: self.start(), text_beside_icon=True) self.stop_button = create_toolbutton(self, icon=ima.icon('stop'), text=_("Stop"), tip=_("Stop current profiling"), text_beside_icon=True) self.filecombo.valid.connect(self.start_button.setEnabled) #self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data) # FIXME: The combobox emits this signal on almost any event # triggering show_data() too early, too often. browse_button = create_toolbutton(self, icon=ima.icon('fileopen'), tip=_('Select Python script'), triggered=self.select_file) self.datelabel = QLabel() self.log_button = create_toolbutton(self, icon=ima.icon('log'), text=_("Output"), text_beside_icon=True, tip=_("Show program's output"), triggered=self.show_log) self.datatree = ProfilerDataTree(self) self.collapse_button = create_toolbutton( self, icon=ima.icon('collapse'), triggered=lambda dD: self.datatree.change_view(-1), tip=_('Collapse one level up')) self.expand_button = create_toolbutton( self, icon=ima.icon('expand'), triggered=lambda dD: self.datatree.change_view(1), tip=_('Expand one level down')) self.save_button = create_toolbutton(self, text_beside_icon=True, text=_("Save data"), icon=ima.icon('filesave'), triggered=self.save_data, tip=_('Save profiling data')) self.load_button = create_toolbutton( self, text_beside_icon=True, text=_("Load data"), icon=ima.icon('fileimport'), triggered=self.compare, tip=_('Load profiling data for comparison')) self.clear_button = create_toolbutton(self, text_beside_icon=True, text=_("Clear comparison"), icon=ima.icon('editdelete'), triggered=self.clear) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_button) if options_button: hlayout1.addWidget(options_button) hlayout2 = QHBoxLayout() hlayout2.addWidget(self.collapse_button) hlayout2.addWidget(self.expand_button) hlayout2.addStretch() hlayout2.addWidget(self.datelabel) hlayout2.addStretch() hlayout2.addWidget(self.log_button) hlayout2.addWidget(self.save_button) hlayout2.addWidget(self.load_button) hlayout2.addWidget(self.clear_button) layout = QVBoxLayout() layout.addLayout(hlayout1) layout.addLayout(hlayout2) layout.addWidget(self.datatree) self.setLayout(layout) self.process = None self.set_running_state(False) self.start_button.setEnabled(False) self.clear_button.setEnabled(False) if not is_profiler_installed(): # This should happen only on certain GNU/Linux distributions # or when this a home-made Python build because the Python # profilers are included in the Python standard library for widget in (self.datatree, self.filecombo, self.start_button, self.stop_button): widget.setDisabled(True) url = 'https://docs.python.org/3/library/profile.html' text = '%s <a href=%s>%s</a>' % (_('Please install'), url, _("the Python profiler modules")) self.datelabel.setText(text) else: pass # self.show_data()
def __init__(self, parent, search_text, search_text_regexp, search_path, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options): QWidget.__init__(self, parent) if search_path is None: search_path = getcwd() self.path = '' self.project_path = None self.file_path = None if not isinstance(search_text, (list, tuple)): search_text = [search_text] if not isinstance(search_path, (list, tuple)): search_path = [search_path] if not isinstance(exclude, (list, tuple)): exclude = [exclude] self.supported_encodings = supported_encodings # Layout 1 hlayout1 = QHBoxLayout() self.search_text = PatternComboBox(self, search_text, _("Search pattern")) self.edit_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.edit_regexp.setCheckable(True) self.edit_regexp.setChecked(search_text_regexp) self.more_widgets = () self.more_options = create_toolbutton(self, toggled=self.toggle_more_options) self.more_options.setCheckable(True) self.more_options.setChecked(more_options) self.ok_button = create_toolbutton(self, text=_("Search"), icon=ima.icon('find'), triggered=lambda: self.find.emit(), tip=_("Start search"), text_beside_icon=True) self.ok_button.clicked.connect(self.update_combos) self.stop_button = create_toolbutton( self, text=_("Stop"), icon=ima.icon('editclear'), triggered=lambda: self.stop.emit(), tip=_("Stop search"), text_beside_icon=True) self.stop_button.setEnabled(False) for widget in [ self.search_text, self.edit_regexp, self.ok_button, self.stop_button, self.more_options ]: hlayout1.addWidget(widget) # Layout 2 hlayout2 = QHBoxLayout() self.exclude_pattern = PatternComboBox(self, exclude, _("Excluded filenames pattern")) if exclude_idx is not None and exclude_idx >= 0 \ and exclude_idx < self.exclude_pattern.count(): self.exclude_pattern.setCurrentIndex(exclude_idx) self.exclude_regexp = create_toolbutton(self, icon=ima.icon('advanced'), tip=_('Regular expression')) self.exclude_regexp.setCheckable(True) self.exclude_regexp.setChecked(exclude_regexp) exclude_label = QLabel(_("Exclude:")) exclude_label.setBuddy(self.exclude_pattern) for widget in [ exclude_label, self.exclude_pattern, self.exclude_regexp ]: hlayout2.addWidget(widget) # Layout 3 hlayout3 = QHBoxLayout() self.global_path_search = QRadioButton(_("Path"), self) self.global_path_search.setChecked(True) self.global_path_search.setToolTip( _("Search in all files and " "directories present on the" "current Spyder path")) self.project_search = QRadioButton(_("Project"), self) self.project_search.setToolTip( _("Search in all files and " "directories present on the" "current project path (If opened)")) self.project_search.setEnabled(False) self.file_search = QRadioButton(_("File"), self) self.file_search.setToolTip(_("Search in current opened file")) for wid in [ self.global_path_search, self.project_search, self.file_search ]: hlayout3.addWidget(wid) hlayout3.addStretch(1) self.search_text.valid.connect(lambda valid: self.find.emit()) self.exclude_pattern.valid.connect(lambda valid: self.find.emit()) vlayout = QVBoxLayout() vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addLayout(hlayout1) vlayout.addLayout(hlayout2) vlayout.addLayout(hlayout3) self.more_widgets = (hlayout2, ) self.toggle_more_options(more_options) self.setLayout(vlayout) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
class UiLinelistsWindow(object): # this code was taken as-is from the Designer. # Cleaning it up sounds like a lower priority # task for now. def setupUi(self, MainWindow, title): MainWindow.setWindowTitle(title) MainWindow.setObjectName("MainWindow") MainWindow.resize(500, 500) MainWindow.setMinimumSize(QSize(300, 350)) self.centralWidget = QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout = QGridLayout(self.centralWidget) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.gridLayout.setSpacing(6) self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.lines_selected_label = QLabel(self.centralWidget) self.lines_selected_label.setObjectName("lines_selected_label") self.horizontalLayout_5.addWidget(self.lines_selected_label) self.label = QLabel(self.centralWidget) self.label.setObjectName("label") self.horizontalLayout_5.addWidget(self.label) self.draw_button = QPushButton(self.centralWidget) self.draw_button.setObjectName("draw_button") self.horizontalLayout_5.addWidget(self.draw_button) self.erase_button = QPushButton(self.centralWidget) self.erase_button.setObjectName("erase_button") self.horizontalLayout_5.addWidget(self.erase_button) self.dismiss_button = QPushButton(self.centralWidget) self.dismiss_button.setObjectName("dismiss_button") self.horizontalLayout_5.addWidget(self.dismiss_button) self.gridLayout.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) self.verticalLayout_11 = QVBoxLayout() self.verticalLayout_11.setContentsMargins(11, 11, 11, 11) self.verticalLayout_11.setSpacing(6) self.verticalLayout_11.setObjectName("verticalLayout_11") self.tabWidget = QTabWidget(self.centralWidget) self.tabWidget.setObjectName("tabWidget") self.verticalLayout_11.addWidget(self.tabWidget) self.gridLayout.addLayout(self.verticalLayout_11, 0, 0, 1, 1) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.add_set_button = QPushButton(self.centralWidget) self.add_set_button.setObjectName("add_set_button") self.horizontalLayout_7.addWidget(self.add_set_button) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem) self.gridLayout.addLayout(self.horizontalLayout_7, 2, 0, 2, 1) MainWindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(MainWindow) self.menuBar.setGeometry(QRect(0, 0, 767, 22)) self.menuBar.setObjectName("menuBar") self.menuFile = QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(MainWindow) self.mainToolBar.setMovable(False) self.mainToolBar.setFloatable(False) self.mainToolBar.setObjectName("mainToolBar") MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.actionOpen = QAction(MainWindow) icon = QIcon() icon.addPixmap(QPixmap(":/img/Open Folder-48.png"), QIcon.Normal, QIcon.Off) self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") self.actionExit = QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionRemove = QAction(MainWindow) self.actionRemove.setObjectName("actionRemove") self.actionChange_Color = QAction(MainWindow) self.actionChange_Color.setObjectName("actionChange_Color") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.mainToolBar.addAction(self.actionOpen) self.mainToolBar.addSeparator() self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QCoreApplication.translate self.lines_selected_label.setText(_translate("MainWindow", "0")) self.label.setText(_translate("MainWindow", "lines selected")) self.draw_button.setText(_translate("MainWindow", "Draw")) self.erase_button.setText(_translate("MainWindow", "Erase")) self.dismiss_button.setText(_translate("MainWindow", "Dismiss")) self.add_set_button.setText(_translate("MainWindow", "Add set")) self.menuFile.setTitle(_translate("MainWindow", "File")) self.actionOpen.setText(_translate("MainWindow", "Open")) self.actionExit.setText(_translate("MainWindow", "Exit")) self.actionRemove.setText(_translate("MainWindow", "Remove")) self.actionRemove.setToolTip( _translate("MainWindow", "Removes the selected layer")) self.actionChange_Color.setText( _translate("MainWindow", "Change Color")) self.actionChange_Color.setToolTip( _translate("MainWindow", "Change the line color selected layer"))
def __init__(self, parent, apply_callback=None): QWidget.__init__(self, parent) self.apply_callback = apply_callback self.is_modified = False
class NapariQtNotification(QDialog): """Notification dialog frame, appears at the bottom right of the canvas. By default, only the first line of the notification is shown, and the text is elided. Double-clicking on the text (or clicking the chevron icon) will expand to show the full notification. The dialog will autmatically disappear in ``DISMISS_AFTER`` milliseconds, unless hovered or clicked. Parameters ---------- message : str The message that will appear in the notification severity : str or NotificationSeverity, optional Severity level {'error', 'warning', 'info', 'none'}. Will determine the icon associated with the message. by default NotificationSeverity.WARNING. source : str, optional A source string for the notifcation (intended to show the module and or package responsible for the notification), by default None actions : list of tuple, optional A sequence of 2-tuples, where each tuple is a string and a callable. Each tuple will be used to create button in the dialog, where the text on the button is determine by the first item in the tuple, and a callback function to call when the button is pressed is the second item in the tuple. by default () """ MAX_OPACITY = 0.9 FADE_IN_RATE = 220 FADE_OUT_RATE = 120 DISMISS_AFTER = 4000 MIN_WIDTH = 400 message: MultilineElidedLabel source_label: QLabel severity_icon: QLabel def __init__( self, message: str, severity: Union[str, NotificationSeverity] = 'WARNING', source: Optional[str] = None, actions: ActionSequence = (), ): super().__init__() from ..qt_main_window import _QtMainWindow current_window = _QtMainWindow.current() if current_window is not None: canvas = current_window.qt_viewer._canvas_overlay self.setParent(canvas) canvas.resized.connect(self.move_to_bottom_right) self.setupUi() self.setAttribute(Qt.WA_DeleteOnClose) self.setup_buttons(actions) self.setMouseTracking(True) self.severity_icon.setText(NotificationSeverity(severity).as_icon()) self.message.setText(message) if source: self.source_label.setText( trans._('Source: {source}', source=source)) self.close_button.clicked.connect(self.close) self.expand_button.clicked.connect(self.toggle_expansion) self.timer = QTimer() self.opacity = QGraphicsOpacityEffect() self.setGraphicsEffect(self.opacity) self.opacity_anim = QPropertyAnimation(self.opacity, b"opacity", self) self.geom_anim = QPropertyAnimation(self, b"geometry", self) self.move_to_bottom_right() def move_to_bottom_right(self, offset=(8, 8)): """Position widget at the bottom right edge of the parent.""" if not self.parent(): return sz = self.parent().size() - self.size() - QSize(*offset) self.move(QPoint(sz.width(), sz.height())) def slide_in(self): """Run animation that fades in the dialog with a slight slide up.""" geom = self.geometry() self.geom_anim.setDuration(self.FADE_IN_RATE) self.geom_anim.setStartValue(geom.translated(0, 20)) self.geom_anim.setEndValue(geom) self.geom_anim.setEasingCurve(QEasingCurve.OutQuad) # fade in self.opacity_anim.setDuration(self.FADE_IN_RATE) self.opacity_anim.setStartValue(0) self.opacity_anim.setEndValue(self.MAX_OPACITY) self.geom_anim.start() self.opacity_anim.start() def show(self): """Show the message with a fade and slight slide in from the bottom.""" super().show() self.slide_in() if self.DISMISS_AFTER > 0: self.timer.setInterval(self.DISMISS_AFTER) self.timer.setSingleShot(True) self.timer.timeout.connect(self.close) self.timer.start() def mouseMoveEvent(self, event): """On hover, stop the self-destruct timer""" self.timer.stop() def mouseDoubleClickEvent(self, event): """Expand the notification on double click.""" self.toggle_expansion() def close(self): """Fade out then close.""" self.opacity_anim.setDuration(self.FADE_OUT_RATE) self.opacity_anim.setStartValue(self.MAX_OPACITY) self.opacity_anim.setEndValue(0) self.opacity_anim.start() self.opacity_anim.finished.connect(super().close) def toggle_expansion(self): """Toggle the expanded state of the notification frame.""" self.contract() if self.property('expanded') else self.expand() self.timer.stop() def expand(self): """Expanded the notification so that the full message is visible.""" curr = self.geometry() self.geom_anim.setDuration(100) self.geom_anim.setStartValue(curr) new_height = self.sizeHint().height() delta = new_height - curr.height() self.geom_anim.setEndValue( QRect(curr.x(), curr.y() - delta, curr.width(), new_height)) self.geom_anim.setEasingCurve(QEasingCurve.OutQuad) self.geom_anim.start() self.setProperty('expanded', True) self.style().unpolish(self.expand_button) self.style().polish(self.expand_button) def contract(self): """Contract notification to a single elided line of the message.""" geom = self.geometry() self.geom_anim.setDuration(100) self.geom_anim.setStartValue(geom) dlt = geom.height() - self.minimumHeight() self.geom_anim.setEndValue( QRect(geom.x(), geom.y() + dlt, geom.width(), geom.height() - dlt)) self.geom_anim.setEasingCurve(QEasingCurve.OutQuad) self.geom_anim.start() self.setProperty('expanded', False) self.style().unpolish(self.expand_button) self.style().polish(self.expand_button) def setupUi(self): """Set up the UI during initialization.""" self.setWindowFlags(Qt.SubWindow) self.setMinimumWidth(self.MIN_WIDTH) self.setMaximumWidth(self.MIN_WIDTH) self.setMinimumHeight(40) self.setSizeGripEnabled(False) self.setModal(False) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setContentsMargins(2, 2, 2, 2) self.verticalLayout.setSpacing(0) self.row1_widget = QWidget(self) self.row1 = QHBoxLayout(self.row1_widget) self.row1.setContentsMargins(12, 12, 12, 8) self.row1.setSpacing(4) self.severity_icon = QLabel(self.row1_widget) self.severity_icon.setObjectName("severity_icon") self.severity_icon.setMinimumWidth(30) self.severity_icon.setMaximumWidth(30) self.row1.addWidget(self.severity_icon, alignment=Qt.AlignTop) self.message = MultilineElidedLabel(self.row1_widget) self.message.setMinimumWidth(self.MIN_WIDTH - 200) self.message.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.row1.addWidget(self.message, alignment=Qt.AlignTop) self.expand_button = QPushButton(self.row1_widget) self.expand_button.setObjectName("expand_button") self.expand_button.setCursor(Qt.PointingHandCursor) self.expand_button.setMaximumWidth(20) self.expand_button.setFlat(True) self.row1.addWidget(self.expand_button, alignment=Qt.AlignTop) self.close_button = QPushButton(self.row1_widget) self.close_button.setObjectName("close_button") self.close_button.setCursor(Qt.PointingHandCursor) self.close_button.setMaximumWidth(20) self.close_button.setFlat(True) self.row1.addWidget(self.close_button, alignment=Qt.AlignTop) self.verticalLayout.addWidget(self.row1_widget, 1) self.row2_widget = QWidget(self) self.row2_widget.hide() self.row2 = QHBoxLayout(self.row2_widget) self.source_label = QLabel(self.row2_widget) self.source_label.setObjectName("source_label") self.row2.addWidget(self.source_label, alignment=Qt.AlignBottom) self.row2.addStretch() self.row2.setContentsMargins(12, 2, 16, 12) self.row2_widget.setMaximumHeight(34) self.row2_widget.setStyleSheet('QPushButton{' 'padding: 4px 12px 4px 12px; ' 'font-size: 11px;' 'min-height: 18px; border-radius: 0;}') self.verticalLayout.addWidget(self.row2_widget, 0) self.setProperty('expanded', False) self.resize(self.MIN_WIDTH, 40) def setup_buttons(self, actions: ActionSequence = ()): """Add buttons to the dialog. Parameters ---------- actions : tuple, optional A sequence of 2-tuples, where each tuple is a string and a callable. Each tuple will be used to create button in the dialog, where the text on the button is determine by the first item in the tuple, and a callback function to call when the button is pressed is the second item in the tuple. by default () """ if isinstance(actions, dict): actions = list(actions.items()) for text, callback in actions: btn = QPushButton(text) def call_back_with_self(callback, self): """ We need a higher order function this to capture the reference to self. """ def _inner(): return callback(self) return _inner btn.clicked.connect(call_back_with_self(callback, self)) btn.clicked.connect(self.close) self.row2.addWidget(btn) if actions: self.row2_widget.show() self.setMinimumHeight(self.row2_widget.maximumHeight() + self.minimumHeight()) def sizeHint(self): """Return the size required to show the entire message.""" return QSize( super().sizeHint().width(), self.row2_widget.height() + self.message.sizeHint().height(), ) @classmethod def from_notification(cls, notification: Notification) -> NapariQtNotification: from ...utils.notifications import ErrorNotification actions = notification.actions if isinstance(notification, ErrorNotification): def show_tb(parent): tbdialog = QDialog(parent=parent.parent()) tbdialog.setModal(True) # this is about the minimum width to not get rewrap # and the minimum height to not have scrollbar tbdialog.resize(650, 270) tbdialog.setLayout(QVBoxLayout()) text = QTextEdit() text.setHtml(notification.as_html()) text.setReadOnly(True) btn = QPushButton(trans._('Enter Debugger')) def _enter_debug_mode(): btn.setText( trans. _('Now Debugging. Please quit debugger in console to continue' )) _debug_tb(notification.exception.__traceback__) btn.setText(trans._('Enter Debugger')) btn.clicked.connect(_enter_debug_mode) tbdialog.layout().addWidget(text) tbdialog.layout().addWidget(btn, 0, Qt.AlignRight) tbdialog.show() actions = tuple(notification.actions) + ( (trans._('View Traceback'), show_tb), ) else: actions = notification.actions return cls( message=notification.message, severity=notification.severity, source=notification.source, actions=actions, ) @classmethod def show_notification(cls, notification: Notification): from ...utils.settings import SETTINGS # after https://github.com/napari/napari/issues/2370, # the os.getenv can be removed (and NAPARI_CATCH_ERRORS retired) if (os.getenv("NAPARI_CATCH_ERRORS") not in ('0', 'False') and notification.severity >= SETTINGS.application.gui_notification_level): application_instance = QApplication.instance() if application_instance: # Check if this is running from a thread if application_instance.thread() != QThread.currentThread(): dispatcher = getattr(application_instance, "_dispatcher", None) if dispatcher: dispatcher.sig_notified.emit(notification) return cls.from_notification(notification).show()
def setupUi(self, MainWindow, title): MainWindow.setWindowTitle(title) MainWindow.setObjectName("MainWindow") MainWindow.resize(500, 500) MainWindow.setMinimumSize(QSize(300, 350)) self.centralWidget = QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout = QGridLayout(self.centralWidget) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.gridLayout.setSpacing(6) self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_5 = QHBoxLayout() self.horizontalLayout_5.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_5.setSpacing(6) self.horizontalLayout_5.setObjectName("horizontalLayout_5") self.lines_selected_label = QLabel(self.centralWidget) self.lines_selected_label.setObjectName("lines_selected_label") self.horizontalLayout_5.addWidget(self.lines_selected_label) self.label = QLabel(self.centralWidget) self.label.setObjectName("label") self.horizontalLayout_5.addWidget(self.label) self.draw_button = QPushButton(self.centralWidget) self.draw_button.setObjectName("draw_button") self.horizontalLayout_5.addWidget(self.draw_button) self.erase_button = QPushButton(self.centralWidget) self.erase_button.setObjectName("erase_button") self.horizontalLayout_5.addWidget(self.erase_button) self.dismiss_button = QPushButton(self.centralWidget) self.dismiss_button.setObjectName("dismiss_button") self.horizontalLayout_5.addWidget(self.dismiss_button) self.gridLayout.addLayout(self.horizontalLayout_5, 4, 0, 1, 1) self.verticalLayout_11 = QVBoxLayout() self.verticalLayout_11.setContentsMargins(11, 11, 11, 11) self.verticalLayout_11.setSpacing(6) self.verticalLayout_11.setObjectName("verticalLayout_11") self.tabWidget = QTabWidget(self.centralWidget) self.tabWidget.setObjectName("tabWidget") self.verticalLayout_11.addWidget(self.tabWidget) self.gridLayout.addLayout(self.verticalLayout_11, 0, 0, 1, 1) self.horizontalLayout_7 = QHBoxLayout() self.horizontalLayout_7.setContentsMargins(11, 11, 11, 11) self.horizontalLayout_7.setSpacing(6) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.add_set_button = QPushButton(self.centralWidget) self.add_set_button.setObjectName("add_set_button") self.horizontalLayout_7.addWidget(self.add_set_button) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_7.addItem(spacerItem) self.gridLayout.addLayout(self.horizontalLayout_7, 2, 0, 2, 1) MainWindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(MainWindow) self.menuBar.setGeometry(QRect(0, 0, 767, 22)) self.menuBar.setObjectName("menuBar") self.menuFile = QMenu(self.menuBar) self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(MainWindow) self.mainToolBar.setMovable(False) self.mainToolBar.setFloatable(False) self.mainToolBar.setObjectName("mainToolBar") MainWindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(MainWindow) self.statusBar.setObjectName("statusBar") MainWindow.setStatusBar(self.statusBar) self.actionOpen = QAction(MainWindow) icon = QIcon() icon.addPixmap(QPixmap(":/img/Open Folder-48.png"), QIcon.Normal, QIcon.Off) self.actionOpen.setIcon(icon) self.actionOpen.setObjectName("actionOpen") self.actionExit = QAction(MainWindow) self.actionExit.setObjectName("actionExit") self.actionRemove = QAction(MainWindow) self.actionRemove.setObjectName("actionRemove") self.actionChange_Color = QAction(MainWindow) self.actionChange_Color.setObjectName("actionChange_Color") self.menuFile.addAction(self.actionOpen) self.menuFile.addSeparator() self.menuFile.addAction(self.actionExit) self.menuBar.addAction(self.menuFile.menuAction()) self.mainToolBar.addAction(self.actionOpen) self.mainToolBar.addSeparator() self.retranslateUi(MainWindow) QMetaObject.connectSlotsByName(MainWindow)
def __init__(self, parent=None, path=''): super().__init__(parent, path) self._path = path _translate = QCoreApplication.translate self.setObjectName("tab_flow") self.base_layout = QHBoxLayout(self) self.verticalLayout_6 = QVBoxLayout() self.base_layout.addLayout(self.verticalLayout_6) self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) self.verticalLayout_6.setSpacing(0) self.verticalLayout_6.setObjectName("verticalLayout_6") self.widget_3 = QWidget(self) self.widget_3.setMinimumSize(QSize(0, 30)) self.widget_3.setObjectName("widget_3") # self.horizontal_layout_down = QHBoxLayout(self.widget_3) self.horizontal_layout = QHBoxLayout(self.widget_3) self.horizontal_layout.setContentsMargins(0, 0, 0, 0) self.horizontal_layout.setSpacing(1) self.horizontal_layout.setObjectName("horizontalLayout_6") self.tool_button_run_fg = QToolButton(self.widget_3) self.tool_button_run_fg.setText('Run_fg') self.horizontal_layout.addWidget(self.tool_button_run_fg) self.tool_button_save = QToolButton(self.widget_3) self.tool_button_save.setText('Save') self.horizontal_layout.addWidget(self.tool_button_save) self.tool_button_reset = QToolButton(self.widget_3) self.tool_button_reset.setText('Reset') self.horizontal_layout.addWidget(self.tool_button_reset) self.tool_button_undo = QToolButton(self.widget_3) self.tool_button_undo.setText('Undo') self.horizontal_layout.addWidget(self.tool_button_undo) self.tool_button_redo = QToolButton(self.widget_3) self.tool_button_redo.setText('Redo') self.horizontal_layout.addWidget(self.tool_button_redo) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontal_layout.addItem(spacerItem) self.verticalLayout_6.addWidget(self.widget_3) self.graphicsView = PMGraphicsView(self) self.graphicsView.setFrameShape(QFrame.NoFrame) self.graphicsView.setObjectName("graphicsView") self.verticalLayout_6.addWidget(self.graphicsView) self.scene = PMGraphicsScene(graphics_view=self.graphicsView, flow_widget=self, allow_multiple_input=True) self.scene.setSceneRect(-1000, -1000, 2000, 2000) self.node_manager = NodeManagerWidget(scene=self.scene) # self.node_manager.scene = self.scene self.base_layout.addWidget(self.node_manager) self.nodes: List[Node] = self.scene.nodes self.lines = self.scene.lines self.node_manager.register_node_content(PMGFlowContent, 'simple_calc', 'UserDefinedFunc') self.load_nodes_library() self.graphicsView.setScene(self.scene) self.tool_button_undo.clicked.connect(self.scene.undo) self.tool_button_redo.clicked.connect(self.scene.redo) # self.tool_button_open.clicked.connect(self.open) self.tool_button_reset.clicked.connect(self.reset) self.tool_button_save.clicked.connect(self.save) self.tool_button_run_fg.clicked.connect(lambda: self.run_in_fg()) if self._path != '': self.scene.load_flowchart(self._path)
def __init__(self, viewer: ViewerModel, show_welcome_screen: bool = False): # Avoid circular import. from .layer_controls import QtLayerControlsContainer super().__init__() self.setAttribute(Qt.WA_DeleteOnClose) self._show_welcome_screen = show_welcome_screen QCoreApplication.setAttribute( Qt.AA_UseStyleSheetPropagationInWidgetStyles, True) self.viewer = viewer self.dims = QtDims(self.viewer.dims) self.controls = QtLayerControlsContainer(self.viewer) self.layers = QtLayerList(self.viewer.layers) self.layerButtons = QtLayerButtons(self.viewer) self.viewerButtons = QtViewerButtons(self.viewer) self._key_map_handler = KeymapHandler() self._key_map_handler.keymap_providers = [self.viewer] self._console = None layerList = QWidget() layerList.setObjectName('layerList') layerListLayout = QVBoxLayout() layerListLayout.addWidget(self.layerButtons) layerListLayout.addWidget(self.layers) layerListLayout.addWidget(self.viewerButtons) layerListLayout.setContentsMargins(8, 4, 8, 6) layerList.setLayout(layerListLayout) self.dockLayerList = QtViewerDockWidget( self, layerList, name=trans._('layer list'), area='left', allowed_areas=['left', 'right'], object_name='layer list', ) self.dockLayerControls = QtViewerDockWidget( self, self.controls, name=trans._('layer controls'), area='left', allowed_areas=['left', 'right'], object_name='layer controls', ) self.dockConsole = QtViewerDockWidget( self, QWidget(), name=trans._('console'), area='bottom', allowed_areas=['top', 'bottom'], object_name='console', ) self.dockConsole.setVisible(False) # because the console is loaded lazily in the @getter, this line just # gets (or creates) the console when the dock console is made visible. self.dockConsole.visibilityChanged.connect(self._ensure_connect) self.dockLayerControls.visibilityChanged.connect(self._constrain_width) self.dockLayerList.setMaximumWidth(258) self.dockLayerList.setMinimumWidth(258) # Only created if using perfmon. self.dockPerformance = self._create_performance_dock_widget() # This dictionary holds the corresponding vispy visual for each layer self.layer_to_visual = {} self._create_canvas() # Stacked widget to provide a welcome page self._canvas_overlay = QtWidgetOverlay(self, self.canvas.native) self._canvas_overlay.set_welcome_visible(show_welcome_screen) self._canvas_overlay.sig_dropped.connect(self.dropEvent) main_widget = QWidget() main_layout = QVBoxLayout() main_layout.setContentsMargins(10, 22, 10, 2) main_layout.addWidget(self._canvas_overlay) main_layout.addWidget(self.dims) main_layout.setSpacing(10) main_widget.setLayout(main_layout) self.setOrientation(Qt.Vertical) self.addWidget(main_widget) self._cursors = { 'cross': Qt.CrossCursor, 'forbidden': Qt.ForbiddenCursor, 'pointing': Qt.PointingHandCursor, 'standard': QCursor(), } self._on_active_change() self.viewer.layers.events.inserted.connect(self._update_welcome_screen) self.viewer.layers.events.removed.connect(self._update_welcome_screen) self.viewer.layers.selection.events.active.connect( self._on_active_change) self.viewer.camera.events.interactive.connect(self._on_interactive) self.viewer.cursor.events.style.connect(self._on_cursor) self.viewer.cursor.events.size.connect(self._on_cursor) self.viewer.layers.events.reordered.connect(self._reorder_layers) self.viewer.layers.events.inserted.connect(self._on_add_layer_change) self.viewer.layers.events.removed.connect(self._remove_layer) self.setAcceptDrops(True) for layer in self.viewer.layers: self._add_layer(layer) self.view = self.canvas.central_widget.add_view(border_width=0) self.camera = VispyCamera(self.view, self.viewer.camera, self.viewer.dims) self.canvas.events.draw.connect(self.camera.on_draw) # Add axes, scale bar self._add_visuals() # Create the experimental QtPool for octree and/or monitor. self._qt_poll = _create_qt_poll(self, self.viewer.camera) # Create the experimental RemoteManager for the monitor. self._remote_manager = _create_remote_manager(self.viewer.layers, self._qt_poll) # moved from the old layerlist... still feels misplaced. # can you help me move this elsewhere? if config.async_loading: from .experimental.qt_chunk_receiver import QtChunkReceiver # The QtChunkReceiver object allows the ChunkLoader to pass newly # loaded chunks to the layers that requested them. self.chunk_receiver = QtChunkReceiver(self.layers) else: self.chunk_receiver = None # bind shortcuts stored in settings last. self._bind_shortcuts()
class PMGSimulationWidget(PMFlowWidget): def __init__(self, parent=None, path=''): super().__init__(parent, path) self._path = path _translate = QCoreApplication.translate self.setObjectName("tab_flow") self.base_layout = QHBoxLayout(self) self.verticalLayout_6 = QVBoxLayout() self.base_layout.addLayout(self.verticalLayout_6) self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) self.verticalLayout_6.setSpacing(0) self.verticalLayout_6.setObjectName("verticalLayout_6") self.widget_3 = QWidget(self) self.widget_3.setMinimumSize(QSize(0, 30)) self.widget_3.setObjectName("widget_3") # self.horizontal_layout_down = QHBoxLayout(self.widget_3) self.horizontal_layout = QHBoxLayout(self.widget_3) self.horizontal_layout.setContentsMargins(0, 0, 0, 0) self.horizontal_layout.setSpacing(1) self.horizontal_layout.setObjectName("horizontalLayout_6") self.tool_button_run_fg = QToolButton(self.widget_3) self.tool_button_run_fg.setText('Run_fg') self.horizontal_layout.addWidget(self.tool_button_run_fg) self.tool_button_save = QToolButton(self.widget_3) self.tool_button_save.setText('Save') self.horizontal_layout.addWidget(self.tool_button_save) self.tool_button_reset = QToolButton(self.widget_3) self.tool_button_reset.setText('Reset') self.horizontal_layout.addWidget(self.tool_button_reset) self.tool_button_undo = QToolButton(self.widget_3) self.tool_button_undo.setText('Undo') self.horizontal_layout.addWidget(self.tool_button_undo) self.tool_button_redo = QToolButton(self.widget_3) self.tool_button_redo.setText('Redo') self.horizontal_layout.addWidget(self.tool_button_redo) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontal_layout.addItem(spacerItem) self.verticalLayout_6.addWidget(self.widget_3) self.graphicsView = PMGraphicsView(self) self.graphicsView.setFrameShape(QFrame.NoFrame) self.graphicsView.setObjectName("graphicsView") self.verticalLayout_6.addWidget(self.graphicsView) self.scene = PMGraphicsScene(graphics_view=self.graphicsView, flow_widget=self, allow_multiple_input=True) self.scene.setSceneRect(-1000, -1000, 2000, 2000) self.node_manager = NodeManagerWidget(scene=self.scene) # self.node_manager.scene = self.scene self.base_layout.addWidget(self.node_manager) self.nodes: List[Node] = self.scene.nodes self.lines = self.scene.lines self.node_manager.register_node_content(PMGFlowContent, 'simple_calc', 'UserDefinedFunc') self.load_nodes_library() self.graphicsView.setScene(self.scene) self.tool_button_undo.clicked.connect(self.scene.undo) self.tool_button_redo.clicked.connect(self.scene.redo) # self.tool_button_open.clicked.connect(self.open) self.tool_button_reset.clicked.connect(self.reset) self.tool_button_save.clicked.connect(self.save) self.tool_button_run_fg.clicked.connect(lambda: self.run_in_fg()) if self._path != '': self.scene.load_flowchart(self._path) # def load_nodes_library(self): # import pmgwidgets.flowchart.nodes.simulation as package_sim # import inspect # for class_name in dir(package_sim): # cls = eval('package_sim.' + class_name) # if inspect.isclass(cls) and issubclass(cls, package_sim.BaseLigralGenerator): # self.node_manager.register_node_content(cls, 'simple_calc') def run_in_fg(self, input_args_list: List[object] = None) -> List[object]: """ 前端直接进行数据处理,而非在后台线程执行。 这样不能做耗时操作(因为会卡住界面),但是可以直接获取运行后的数据,并且结果相对简单一些。 :return: """ from pmgwidgets.flowchart.nodes.simulation import BaseLigralGenerator j_list = [] for node in self.scene.nodes: content: BaseLigralGenerator = node.content j_list.append(content.generate_ligjson()) print(content.generate_ligjson()) text = json.dumps(j_list, indent=4) print(text) ligral_path = r'c:\users\12957\Desktop\ligral.exe' file_path = os.path.join(os.path.dirname(__file__), 'temp.lig.json') with open(file_path, 'w') as f: f.write(text) from pmgwidgets.utilities.platform import run_command_in_terminal_block run_command_in_terminal_block('%s %s --json' % (ligral_path, file_path))
class Window: """Application window that contains the menu bar and viewer. Parameters ---------- qt_viewer : QtViewer Contained viewer widget. Attributes ---------- file_menu : qtpy.QtWidgets.QMenu File menu. help_menu : qtpy.QtWidgets.QMenu Help menu. main_menu : qtpy.QtWidgets.QMainWindow.menuBar Main menubar. qt_viewer : QtViewer Contained viewer widget. view_menu : qtpy.QtWidgets.QMenu View menu. window_menu : qtpy.QtWidgets.QMenu Window menu. """ raw_stylesheet = get_stylesheet() def __init__(self, qt_viewer: QtViewer, *, show: bool = True): self.qt_viewer = qt_viewer self._qt_window = QMainWindow() self._qt_window.setAttribute(Qt.WA_DeleteOnClose) self._qt_window.setUnifiedTitleAndToolBarOnMac(True) # since we initialize canvas before window, we need to manually connect them again. if self._qt_window.windowHandle() is not None: self._qt_window.windowHandle().screenChanged.connect( self.qt_viewer.canvas._backend.screen_changed) self._qt_center = QWidget(self._qt_window) self._qt_window.setCentralWidget(self._qt_center) self._qt_window.setWindowTitle(self.qt_viewer.viewer.title) self._qt_center.setLayout(QHBoxLayout()) self._status_bar = QStatusBar() self._qt_window.setStatusBar(self._status_bar) self._add_menubar() self._add_file_menu() self._add_view_menu() self._add_window_menu() self._add_plugins_menu() self._add_help_menu() self._status_bar.showMessage('Ready') self._help = QLabel('') self._status_bar.addPermanentWidget(self._help) self._qt_center.layout().addWidget(self.qt_viewer) self._qt_center.layout().setContentsMargins(4, 0, 4, 0) self._update_palette() self._add_viewer_dock_widget(self.qt_viewer.dockConsole) self._add_viewer_dock_widget(self.qt_viewer.dockLayerControls) self._add_viewer_dock_widget(self.qt_viewer.dockLayerList) self.qt_viewer.viewer.events.status.connect(self._status_changed) self.qt_viewer.viewer.events.help.connect(self._help_changed) self.qt_viewer.viewer.events.title.connect(self._title_changed) self.qt_viewer.viewer.events.palette.connect(self._update_palette) if perf.USE_PERFMON: # Add DebugMenu and dockPerformance if using perfmon. self._debug_menu = DebugMenu(self) self._add_viewer_dock_widget(self.qt_viewer.dockPerformance) else: self._debug_menu = None if self.qt_viewer.dockRender is not None: self._add_viewer_dock_widget(self.qt_viewer.dockRender) if show: self.show() def _add_menubar(self): """Add menubar to napari app.""" self.main_menu = self._qt_window.menuBar() # Menubar shortcuts are only active when the menubar is visible. # Therefore, we set a global shortcut not associated with the menubar # to toggle visibility, *but*, in order to not shadow the menubar # shortcut, we disable it, and only enable it when the menubar is # hidden. See this stackoverflow link for details: # https://stackoverflow.com/questions/50537642/how-to-keep-the-shortcuts-of-a-hidden-widget-in-pyqt5 self._main_menu_shortcut = QShortcut(QKeySequence('Ctrl+M'), self._qt_window) self._main_menu_shortcut.activated.connect( self._toggle_menubar_visible) self._main_menu_shortcut.setEnabled(False) def _toggle_menubar_visible(self): """Toggle visibility of app menubar. This function also disables or enables a global keyboard shortcut to show the menubar, since menubar shortcuts are only available while the menubar is visible. """ if self.main_menu.isVisible(): self.main_menu.setVisible(False) self._main_menu_shortcut.setEnabled(True) else: self.main_menu.setVisible(True) self._main_menu_shortcut.setEnabled(False) def _add_file_menu(self): """Add 'File' menu to app menubar.""" open_images = QAction('Open File(s)...', self._qt_window) open_images.setShortcut('Ctrl+O') open_images.setStatusTip('Open file(s)') open_images.triggered.connect(self.qt_viewer._open_files_dialog) open_stack = QAction('Open Files as Stack...', self._qt_window) open_stack.setShortcut('Ctrl+Alt+O') open_stack.setStatusTip('Open files') open_stack.triggered.connect( self.qt_viewer._open_files_dialog_as_stack_dialog) open_folder = QAction('Open Folder...', self._qt_window) open_folder.setShortcut('Ctrl+Shift+O') open_folder.setStatusTip('Open a folder') open_folder.triggered.connect(self.qt_viewer._open_folder_dialog) save_selected_layers = QAction('Save Selected Layer(s)...', self._qt_window) save_selected_layers.setShortcut('Ctrl+S') save_selected_layers.setStatusTip('Save selected layers') save_selected_layers.triggered.connect( lambda: self.qt_viewer._save_layers_dialog(selected=True)) save_all_layers = QAction('Save All Layers...', self._qt_window) save_all_layers.setShortcut('Ctrl+Shift+S') save_all_layers.setStatusTip('Save all layers') save_all_layers.triggered.connect( lambda: self.qt_viewer._save_layers_dialog(selected=False)) screenshot = QAction('Save Screenshot...', self._qt_window) screenshot.setShortcut('Alt+S') screenshot.setStatusTip( 'Save screenshot of current display, default .png') screenshot.triggered.connect(self.qt_viewer._screenshot_dialog) screenshot_wv = QAction('Save Screenshot with Viewer...', self._qt_window) screenshot_wv.setShortcut('Alt+Shift+S') screenshot_wv.setStatusTip( 'Save screenshot of current display with the viewer, default .png') screenshot_wv.triggered.connect(self._screenshot_dialog) # OS X will rename this to Quit and put it in the app menu. exitAction = QAction('Exit', self._qt_window) exitAction.setShortcut('Ctrl+Q') exitAction.setMenuRole(QAction.QuitRole) def handle_exit(): # if the event loop was started in gui_qt() then the app will be # named 'napari'. Since the Qapp was started by us, just close it. if QApplication.applicationName() == 'napari': QApplication.closeAllWindows() QApplication.quit() # otherwise, something else created the QApp before us (such as # %gui qt IPython magic). If we quit the app in this case, then # *later* attempts to instantiate a napari viewer won't work until # the event loop is restarted with app.exec_(). So rather than # quit just close all the windows (and clear our app icon). else: QApplication.setWindowIcon(QIcon()) self.close() if perf.USE_PERFMON: # Write trace file before exit, if we were writing one. # Is there a better place to make sure this is done on exit? perf.timers.stop_trace_file() exitAction.triggered.connect(handle_exit) self.file_menu = self.main_menu.addMenu('&File') self.file_menu.addAction(open_images) self.file_menu.addAction(open_stack) self.file_menu.addAction(open_folder) self.file_menu.addSeparator() self.file_menu.addAction(save_selected_layers) self.file_menu.addAction(save_all_layers) self.file_menu.addAction(screenshot) self.file_menu.addAction(screenshot_wv) self.file_menu.addSeparator() self.file_menu.addAction(exitAction) def _add_view_menu(self): """Add 'View' menu to app menubar.""" toggle_visible = QAction('Toggle Menubar Visibility', self._qt_window) toggle_visible.setShortcut('Ctrl+M') toggle_visible.setStatusTip('Hide Menubar') toggle_visible.triggered.connect(self._toggle_menubar_visible) toggle_theme = QAction('Toggle Theme', self._qt_window) toggle_theme.setShortcut('Ctrl+Shift+T') toggle_theme.setStatusTip('Toggle theme') toggle_theme.triggered.connect(self.qt_viewer.viewer._toggle_theme) self.view_menu = self.main_menu.addMenu('&View') self.view_menu.addAction(toggle_visible) self.view_menu.addAction(toggle_theme) self.view_menu.addSeparator() # Add axes menu axes_menu = QMenu('Axes', parent=self._qt_window) axes_visible_action = QAction( 'Visible', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.visible, ) axes_visible_action.triggered.connect(self._toggle_axes_visible) axes_colored_action = QAction( 'Colored', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.colored, ) axes_colored_action.triggered.connect(self._toggle_axes_colored) axes_dashed_action = QAction( 'Dashed', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.dashed, ) axes_dashed_action.triggered.connect(self._toggle_axes_dashed) axes_arrows_action = QAction( 'Arrows', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.axes.arrows, ) axes_arrows_action.triggered.connect(self._toggle_axes_arrows) axes_menu.addAction(axes_visible_action) axes_menu.addAction(axes_colored_action) axes_menu.addAction(axes_dashed_action) axes_menu.addAction(axes_arrows_action) self.view_menu.addMenu(axes_menu) # Add scale bar menu scale_bar_menu = QMenu('Scale Bar', parent=self._qt_window) scale_bar_visible_action = QAction( 'Visible', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.visible, ) scale_bar_visible_action.triggered.connect( self._toggle_scale_bar_visible) scale_bar_colored_action = QAction( 'Colored', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.colored, ) scale_bar_colored_action.triggered.connect( self._toggle_scale_bar_colored) scale_bar_ticks_action = QAction( 'Ticks', parent=self._qt_window, checkable=True, checked=self.qt_viewer.viewer.scale_bar.ticks, ) scale_bar_ticks_action.triggered.connect(self._toggle_scale_bar_ticks) scale_bar_menu.addAction(scale_bar_visible_action) scale_bar_menu.addAction(scale_bar_colored_action) scale_bar_menu.addAction(scale_bar_ticks_action) self.view_menu.addMenu(scale_bar_menu) self.view_menu.addSeparator() def _add_window_menu(self): """Add 'Window' menu to app menubar.""" exit_action = QAction("Close Window", self._qt_window) exit_action.setShortcut("Ctrl+W") exit_action.setStatusTip('Close napari window') exit_action.triggered.connect(self._qt_window.close) self.window_menu = self.main_menu.addMenu('&Window') self.window_menu.addAction(exit_action) def _add_plugins_menu(self): """Add 'Plugins' menu to app menubar.""" self.plugins_menu = self.main_menu.addMenu('&Plugins') list_plugins_action = QAction("List Installed Plugins...", self._qt_window) list_plugins_action.setStatusTip('List installed plugins') list_plugins_action.triggered.connect(self._show_plugin_list) self.plugins_menu.addAction(list_plugins_action) pip_install_action = QAction("Install/Uninstall Package(s)...", self._qt_window) pip_install_action.triggered.connect(self._show_pip_install_dialog) self.plugins_menu.addAction(pip_install_action) order_plugin_action = QAction("Plugin Call Order...", self._qt_window) order_plugin_action.setStatusTip('Change call order for plugins') order_plugin_action.triggered.connect(self._show_plugin_sorter) self.plugins_menu.addAction(order_plugin_action) report_plugin_action = QAction("Plugin Errors...", self._qt_window) report_plugin_action.setStatusTip( 'Review stack traces for plugin exceptions and notify developers') report_plugin_action.triggered.connect(self._show_plugin_err_reporter) self.plugins_menu.addAction(report_plugin_action) def _show_plugin_list(self, plugin_manager=None): """Show dialog with a table of installed plugins and metadata.""" QtPluginTable(self._qt_window).exec_() def _show_plugin_sorter(self): """Show dialog that allows users to sort the call order of plugins.""" plugin_sorter = QtPluginSorter(parent=self._qt_window) dock_widget = self.add_dock_widget(plugin_sorter, name='Plugin Sorter', area="right") plugin_sorter.finished.connect(dock_widget.close) plugin_sorter.finished.connect(plugin_sorter.deleteLater) plugin_sorter.finished.connect(dock_widget.deleteLater) def _show_pip_install_dialog(self): """Show dialog that allows users to sort the call order of plugins.""" from .qt_pip_dialog import QtPipDialog dialog = QtPipDialog(self._qt_window) dialog.exec_() def _show_plugin_err_reporter(self): """Show dialog that allows users to review and report plugin errors.""" plugin_sorter = QtPluginErrReporter(parent=self._qt_window) plugin_sorter.exec_() def _add_help_menu(self): """Add 'Help' menu to app menubar.""" self.help_menu = self.main_menu.addMenu('&Help') about_action = QAction("napari Info", self._qt_window) about_action.setShortcut("Ctrl+/") about_action.setStatusTip('About napari') about_action.triggered.connect( lambda e: QtAbout.showAbout(self.qt_viewer)) self.help_menu.addAction(about_action) about_key_bindings = QAction("Show Key Bindings", self._qt_window) about_key_bindings.setShortcut("Ctrl+Alt+/") about_key_bindings.setShortcutContext(Qt.ApplicationShortcut) about_key_bindings.setStatusTip('key_bindings') about_key_bindings.triggered.connect( self.qt_viewer.show_key_bindings_dialog) self.help_menu.addAction(about_key_bindings) def _toggle_scale_bar_visible(self, state): self.qt_viewer.viewer.scale_bar.visible = state def _toggle_scale_bar_colored(self, state): self.qt_viewer.viewer.scale_bar.colored = state def _toggle_scale_bar_ticks(self, state): self.qt_viewer.viewer.scale_bar.ticks = state def _toggle_axes_visible(self, state): self.qt_viewer.viewer.axes.visible = state def _toggle_axes_colored(self, state): self.qt_viewer.viewer.axes.colored = state def _toggle_axes_dashed(self, state): self.qt_viewer.viewer.axes.dashed = state def _toggle_axes_arrows(self, state): self.qt_viewer.viewer.axes.arrows = state def add_dock_widget( self, widget: QWidget, *, name: str = '', area: str = 'bottom', allowed_areas=None, shortcut=None, ): """Convenience method to add a QDockWidget to the main window Parameters ---------- widget : QWidget `widget` will be added as QDockWidget's main widget. name : str, optional Name of dock widget to appear in window menu. area : str Side of the main window to which the new dock widget will be added. Must be in {'left', 'right', 'top', 'bottom'} allowed_areas : list[str], optional Areas, relative to main window, that the widget is allowed dock. Each item in list must be in {'left', 'right', 'top', 'bottom'} By default, all areas are allowed. shortcut : str, optional Keyboard shortcut to appear in dropdown menu. Returns ------- dock_widget : QtViewerDockWidget `dock_widget` that can pass viewer events. """ dock_widget = QtViewerDockWidget( self.qt_viewer, widget, name=name, area=area, allowed_areas=allowed_areas, shortcut=shortcut, ) self._add_viewer_dock_widget(dock_widget) return dock_widget def _add_viewer_dock_widget(self, dock_widget: QtViewerDockWidget): """Add a QtViewerDockWidget to the main window Parameters ---------- dock_widget : QtViewerDockWidget `dock_widget` will be added to the main window. """ dock_widget.setParent(self._qt_window) self._qt_window.addDockWidget(dock_widget.qt_area, dock_widget) action = dock_widget.toggleViewAction() action.setStatusTip(dock_widget.name) action.setText(dock_widget.name) if dock_widget.shortcut is not None: action.setShortcut(dock_widget.shortcut) self.window_menu.addAction(action) def remove_dock_widget(self, widget): """Removes specified dock widget. Parameters ---------- widget : QWidget | str If widget == 'all', all docked widgets will be removed. """ if widget == 'all': for dw in self._qt_window.findChildren(QDockWidget): self._qt_window.removeDockWidget(dw) else: self._qt_window.removeDockWidget(widget) def resize(self, width, height): """Resize the window. Parameters ---------- width : int Width in logical pixels. height : int Height in logical pixels. """ self._qt_window.resize(width, height) def show(self): """Resize, show, and bring forward the window.""" self._qt_window.resize(self._qt_window.layout().sizeHint()) self._qt_window.show() # Resize axis labels now that window is shown self.qt_viewer.dims._resize_axis_labels() # We want to bring the viewer to the front when # A) it is our own (gui_qt) event loop OR we are running in jupyter # B) it is not the first time a QMainWindow is being created # `app_name` will be "napari" iff the application was instantiated in # gui_qt(). isActiveWindow() will be True if it is the second time a # _qt_window has been created. # See #721, #732, #735, #795, #1594 app_name = QApplication.instance().applicationName() if (app_name == 'napari' or in_jupyter()) and self._qt_window.isActiveWindow(): self.activate() def activate(self): """Make the viewer the currently active window.""" self._qt_window.raise_() # for macOS self._qt_window.activateWindow() # for Windows def _update_palette(self, event=None): """Update widget color palette.""" # set window styles which don't use the primary stylesheet # FIXME: this is a problem with the stylesheet not using properties palette = self.qt_viewer.viewer.palette self._status_bar.setStyleSheet( template( 'QStatusBar { background: {{ background }}; ' 'color: {{ text }}; }', **palette, )) self._qt_center.setStyleSheet( template('QWidget { background: {{ background }}; }', **palette)) self._qt_window.setStyleSheet(template(self.raw_stylesheet, **palette)) def _status_changed(self, event): """Update status bar. Parameters ---------- event : napari.utils.event.Event The napari event that triggered this method. """ self._status_bar.showMessage(event.text) def _title_changed(self, event): """Update window title. Parameters ---------- event : napari.utils.event.Event The napari event that triggered this method. """ self._qt_window.setWindowTitle(event.text) def _help_changed(self, event): """Update help message on status bar. Parameters ---------- event : napari.utils.event.Event The napari event that triggered this method. """ self._help.setText(event.text) def _screenshot_dialog(self): """Save screenshot of current display with viewer, default .png""" dial = ScreenshotDialog(self.screenshot, self.qt_viewer, self.qt_viewer._last_visited_dir) if dial.exec_(): self._last_visited_dir = os.path.dirname(dial.selectedFiles()[0]) def screenshot(self, path=None): """Take currently displayed viewer and convert to an image array. Parameters ---------- path : str Filename for saving screenshot image. Returns ------- image : array Numpy array of type ubyte and shape (h, w, 4). Index [0, 0] is the upper-left corner of the rendered region. """ img = self._qt_window.grab().toImage() if path is not None: imsave(path, QImg2array(img)) # scikit-image imsave method return QImg2array(img) def close(self): """Close the viewer window and cleanup sub-widgets.""" # Someone is closing us twice? Only try to delete self._qt_window # if we still have one. if hasattr(self, '_qt_window'): self._delete_qt_window() def _delete_qt_window(self): """Delete our self._qt_window.""" # On some versions of Darwin, exiting while fullscreen seems to tickle # some bug deep in NSWindow. This forces the fullscreen keybinding # test to complete its draw cycle, then pop back out of fullscreen. if self._qt_window.isFullScreen(): self._qt_window.showNormal() for i in range(8): time.sleep(0.1) QApplication.processEvents() self.qt_viewer.close() self._qt_window.close() del self._qt_window
def __init__(self, parent): QWidget.__init__(self, parent) self.parent = parent # Variables to adjust self.duration_canvas = [666, 666] self.duration_tips = [333, 333] self.opacity_canvas = [0.0, 0.7] self.opacity_tips = [0.0, 1.0] self.color = Qt.black self.easing_curve = [QEasingCurve.Linear] self.current_step = 0 self.step_current = 0 self.steps = 0 self.canvas = None self.tips = None self.frames = None self.spy_window = None self.widgets = None self.dockwidgets = None self.decoration = None self.run = None self.is_tour_set = False self.is_running = False # Widgets self.canvas = FadingCanvas(self.parent, self.opacity_canvas, self.duration_canvas, self.easing_curve, self.color, tour=self) self.tips = FadingTipBox(self.parent, self.opacity_tips, self.duration_tips, self.easing_curve, tour=self) # Widgets setup # Needed to fix issue #2204 self.setAttribute(Qt.WA_TransparentForMouseEvents) # Signals and slots self.tips.button_next.clicked.connect(self.next_step) self.tips.button_previous.clicked.connect(self.previous_step) self.tips.button_close.clicked.connect(self.close_tour) self.tips.button_run.clicked.connect(self.run_code) self.tips.button_home.clicked.connect(self.first_step) self.tips.button_end.clicked.connect(self.last_step) self.tips.button_run.clicked.connect( lambda: self.tips.button_run.setDisabled(True)) self.tips.combo_title.currentIndexChanged.connect(self.go_to_step) # Main window move or resize self.parent.sig_resized.connect(self._resized) self.parent.sig_moved.connect(self._moved) # To capture the arrow keys that allow moving the tour self.tips.sig_key_pressed.connect(self._key_pressed) # To control the focus of tour self.setting_data = False self.hidden = False
def __init__(self, parent): QWidget.__init__(self, parent) SpyderPluginMixin.__init__(self, parent)
def __init__(self, parent): QWidget.__init__(self) self.parent = parent self.layout = QHBoxLayout() self.layout.setAlignment(Qt.AlignLeft)
def __init__(self, parent=None, name_filters=['*.py', '*.pyw'], show_all=False, show_cd_only=None, show_icontext=True): QWidget.__init__(self, parent) # Widgets self.treewidget = ExplorerTreeWidget(self, show_cd_only=show_cd_only) button_previous = QToolButton(self) button_next = QToolButton(self) button_parent = QToolButton(self) self.button_menu = QToolButton(self) menu = QMenu(self) self.action_widgets = [ button_previous, button_next, button_parent, self.button_menu ] # Actions icontext_action = create_action(self, _("Show icons and text"), toggled=self.toggle_icontext) previous_action = create_action( self, text=_("Previous"), icon=ima.icon('ArrowBack'), triggered=self.treewidget.go_to_previous_directory) next_action = create_action( self, text=_("Next"), icon=ima.icon('ArrowForward'), triggered=self.treewidget.go_to_next_directory) parent_action = create_action( self, text=_("Parent"), icon=ima.icon('ArrowUp'), triggered=self.treewidget.go_to_parent_directory) options_action = create_action(self, text='', tip=_('Options')) # Setup widgets self.treewidget.setup(name_filters=name_filters, show_all=show_all) self.treewidget.chdir(getcwd()) self.treewidget.common_actions += [None, icontext_action] button_previous.setDefaultAction(previous_action) previous_action.setEnabled(False) button_next.setDefaultAction(next_action) next_action.setEnabled(False) button_parent.setDefaultAction(parent_action) self.button_menu.setIcon(ima.icon('tooloptions')) self.button_menu.setPopupMode(QToolButton.InstantPopup) self.button_menu.setMenu(menu) add_actions(menu, self.treewidget.common_actions) options_action.setMenu(menu) self.toggle_icontext(show_icontext) icontext_action.setChecked(show_icontext) for widget in self.action_widgets: widget.setAutoRaise(True) widget.setIconSize(QSize(16, 16)) # Layouts blayout = QHBoxLayout() blayout.addWidget(button_previous) blayout.addWidget(button_next) blayout.addWidget(button_parent) blayout.addStretch() blayout.addWidget(self.button_menu) layout = QVBoxLayout() layout.addLayout(blayout) layout.addWidget(self.treewidget) self.setLayout(layout) # Signals and slots self.treewidget.set_previous_enabled.connect( previous_action.setEnabled) self.treewidget.set_next_enabled.connect(next_action.setEnabled)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.dir = None self.runconf = RunConfiguration() firstrun_o = CONF.get('run', ALWAYS_OPEN_FIRST_RUN_OPTION, False) # --- Run settings --- self.run_default_config_radio = QRadioButton(RUN_DEFAULT_CONFIG) self.run_custom_config_radio = QRadioButton(RUN_CUSTOM_CONFIG) # --- Interpreter --- interpreter_group = QGroupBox(_("Console")) interpreter_group.setDisabled(True) self.run_custom_config_radio.toggled.connect( interpreter_group.setEnabled) interpreter_layout = QVBoxLayout(interpreter_group) self.current_radio = QRadioButton(CURRENT_INTERPRETER) interpreter_layout.addWidget(self.current_radio) self.dedicated_radio = QRadioButton(DEDICATED_INTERPRETER) interpreter_layout.addWidget(self.dedicated_radio) self.systerm_radio = QRadioButton(SYSTERM_INTERPRETER) interpreter_layout.addWidget(self.systerm_radio) # --- System terminal --- external_group = QWidget() external_group.setDisabled(True) self.systerm_radio.toggled.connect(external_group.setEnabled) external_layout = QGridLayout() external_group.setLayout(external_layout) self.interact_cb = QCheckBox(INTERACT) external_layout.addWidget(self.interact_cb, 1, 0, 1, -1) self.pclo_cb = QCheckBox(_("Command line options:")) external_layout.addWidget(self.pclo_cb, 3, 0) self.pclo_edit = QLineEdit() self.pclo_cb.toggled.connect(self.pclo_edit.setEnabled) self.pclo_edit.setEnabled(False) self.pclo_edit.setToolTip(_("<b>-u</b> is added to the " "other options you set here")) external_layout.addWidget(self.pclo_edit, 3, 1) interpreter_layout.addWidget(external_group) # --- General settings ---- common_group = QGroupBox(_("General settings")) common_group.setDisabled(True) self.run_custom_config_radio.toggled.connect(common_group.setEnabled) common_layout = QGridLayout(common_group) self.clear_var_cb = QCheckBox(CLEAR_ALL_VARIABLES) common_layout.addWidget(self.clear_var_cb, 0, 0) self.console_ns_cb = QCheckBox(CONSOLE_NAMESPACE) common_layout.addWidget(self.console_ns_cb, 1, 0) self.post_mortem_cb = QCheckBox(POST_MORTEM) common_layout.addWidget(self.post_mortem_cb, 2, 0) self.clo_cb = QCheckBox(_("Command line options:")) common_layout.addWidget(self.clo_cb, 3, 0) self.clo_edit = QLineEdit() self.clo_cb.toggled.connect(self.clo_edit.setEnabled) self.clo_edit.setEnabled(False) common_layout.addWidget(self.clo_edit, 3, 1) # --- Working directory --- wdir_group = QGroupBox(_("Working directory settings")) wdir_group.setDisabled(True) self.run_custom_config_radio.toggled.connect(wdir_group.setEnabled) wdir_layout = QVBoxLayout(wdir_group) self.file_dir_radio = QRadioButton(FILE_DIR) wdir_layout.addWidget(self.file_dir_radio) self.cwd_radio = QRadioButton(CW_DIR) wdir_layout.addWidget(self.cwd_radio) fixed_dir_layout = QHBoxLayout() self.fixed_dir_radio = QRadioButton(FIXED_DIR) fixed_dir_layout.addWidget(self.fixed_dir_radio) self.wd_edit = QLineEdit() self.fixed_dir_radio.toggled.connect(self.wd_edit.setEnabled) self.wd_edit.setEnabled(False) fixed_dir_layout.addWidget(self.wd_edit) browse_btn = create_toolbutton( self, triggered=self.select_directory, icon=ima.icon('DirOpenIcon'), tip=_("Select directory") ) fixed_dir_layout.addWidget(browse_btn) wdir_layout.addLayout(fixed_dir_layout) # Checkbox to preserve the old behavior, i.e. always open the dialog # on first run self.firstrun_cb = QCheckBox(ALWAYS_OPEN_FIRST_RUN % _("this dialog")) self.firstrun_cb.clicked.connect(self.set_firstrun_o) self.firstrun_cb.setChecked(firstrun_o) layout = QVBoxLayout(self) layout.addWidget(self.run_default_config_radio) layout.addWidget(self.run_custom_config_radio) layout.addWidget(interpreter_group) layout.addWidget(common_group) layout.addWidget(wdir_group) layout.addWidget(self.firstrun_cb) layout.addStretch(100)
def setup_page(self): newcb = self.create_checkbox # --- Display tab --- showtabbar_box = newcb(_("Show tab bar"), 'show_tab_bar') showclassfuncdropdown_box = newcb( _("Show selector for classes and functions"), 'show_class_func_dropdown') showindentguides_box = newcb(_("Show indent guides"), 'indent_guides') showcodefolding_box = newcb(_("Show code folding"), 'code_folding') linenumbers_box = newcb(_("Show line numbers"), 'line_numbers') blanks_box = newcb(_("Show blank spaces"), 'blank_spaces') currentline_box = newcb(_("Highlight current line"), 'highlight_current_line') currentcell_box = newcb(_("Highlight current cell"), 'highlight_current_cell') wrap_mode_box = newcb(_("Wrap lines"), 'wrap') scroll_past_end_box = newcb(_("Scroll past the end"), 'scroll_past_end') edgeline_box = newcb(_("Show vertical lines at"), 'edge_line') edgeline_edit = self.create_lineedit( "", 'edge_line_columns', tip=("Enter values separated by commas"), alignment=Qt.Horizontal, regex="[0-9]+(,[0-9]+)*") edgeline_edit_label = QLabel(_("characters")) edgeline_box.toggled.connect(edgeline_edit.setEnabled) edgeline_box.toggled.connect(edgeline_edit_label.setEnabled) edgeline_edit.setEnabled(self.get_option('edge_line')) edgeline_edit_label.setEnabled(self.get_option('edge_line')) occurrence_box = newcb(_("Highlight occurrences after"), 'occurrence_highlighting') occurrence_spin = self.create_spinbox( "", _(" ms"), 'occurrence_highlighting/timeout', min_=100, max_=1000000, step=100) occurrence_box.toggled.connect(occurrence_spin.spinbox.setEnabled) occurrence_box.toggled.connect(occurrence_spin.slabel.setEnabled) occurrence_spin.spinbox.setEnabled( self.get_option('occurrence_highlighting')) occurrence_spin.slabel.setEnabled( self.get_option('occurrence_highlighting')) display_g_layout = QGridLayout() display_g_layout.addWidget(edgeline_box, 0, 0) display_g_layout.addWidget(edgeline_edit.textbox, 0, 1) display_g_layout.addWidget(edgeline_edit_label, 0, 2) display_g_layout.addWidget(occurrence_box, 1, 0) display_g_layout.addWidget(occurrence_spin.spinbox, 1, 1) display_g_layout.addWidget(occurrence_spin.slabel, 1, 2) display_h_layout = QHBoxLayout() display_h_layout.addLayout(display_g_layout) display_h_layout.addStretch(1) display_layout = QVBoxLayout() display_layout.addWidget(showtabbar_box) display_layout.addWidget(showclassfuncdropdown_box) display_layout.addWidget(showindentguides_box) display_layout.addWidget(showcodefolding_box) display_layout.addWidget(linenumbers_box) display_layout.addWidget(blanks_box) display_layout.addWidget(currentline_box) display_layout.addWidget(currentcell_box) display_layout.addWidget(wrap_mode_box) display_layout.addWidget(scroll_past_end_box) display_layout.addLayout(display_h_layout) display_widget = QWidget() display_widget.setLayout(display_layout) # --- Source code tab --- closepar_box = newcb( _("Automatic insertion of parentheses, braces and brackets"), 'close_parentheses') close_quotes_box = newcb(_("Automatic insertion of closing quotes"), 'close_quotes') add_colons_box = newcb( _("Automatic insertion of colons after 'for', 'if', 'def', etc"), 'add_colons') autounindent_box = newcb( _("Automatic indentation after 'else', 'elif', etc."), 'auto_unindent') tab_mode_box = newcb( _("Tab always indent"), 'tab_always_indent', default=False, tip=_("If enabled, pressing Tab will always indent,\n" "even when the cursor is not at the beginning\n" "of a line (when this option is enabled, code\n" "completion may be triggered using the alternate\n" "shortcut: Ctrl+Space)")) strip_mode_box = newcb( _("Automatically strip trailing spaces on changed lines"), 'strip_trailing_spaces_on_modify', default=True, tip= _("If enabled, modified lines of code (excluding strings)\n" "will have their trailing whitespace stripped when leaving them.\n" "If disabled, only whitespace added by Spyder will be stripped." )) ibackspace_box = newcb(_("Intelligent backspace"), 'intelligent_backspace', default=True) removetrail_box = newcb( _("Automatically remove trailing spaces when saving files"), 'always_remove_trailing_spaces', default=False) indent_chars_box = self.create_combobox( _("Indentation characters: "), ((_("2 spaces"), '* *'), (_("3 spaces"), '* *'), (_("4 spaces"), '* *'), (_("5 spaces"), '* *'), (_("6 spaces"), '* *'), (_("7 spaces"), '* *'), (_("8 spaces"), '* *'), (_("Tabulations"), '*\t*')), 'indent_chars') tabwidth_spin = self.create_spinbox(_("Tab stop width:"), _("spaces"), 'tab_stop_width_spaces', default=4, min_=1, max_=8, step=1) def enable_tabwidth_spin(index): if index == 7: # Tabulations tabwidth_spin.plabel.setEnabled(True) tabwidth_spin.spinbox.setEnabled(True) else: tabwidth_spin.plabel.setEnabled(False) tabwidth_spin.spinbox.setEnabled(False) indent_chars_box.combobox.currentIndexChanged.connect( enable_tabwidth_spin) indent_tab_grid_layout = QGridLayout() indent_tab_grid_layout.addWidget(indent_chars_box.label, 0, 0) indent_tab_grid_layout.addWidget(indent_chars_box.combobox, 0, 1) indent_tab_grid_layout.addWidget(tabwidth_spin.plabel, 1, 0) indent_tab_grid_layout.addWidget(tabwidth_spin.spinbox, 1, 1) indent_tab_grid_layout.addWidget(tabwidth_spin.slabel, 1, 2) indent_tab_layout = QHBoxLayout() indent_tab_layout.addLayout(indent_tab_grid_layout) indent_tab_layout.addStretch(1) sourcecode_layout = QVBoxLayout() sourcecode_layout.addWidget(closepar_box) sourcecode_layout.addWidget(autounindent_box) sourcecode_layout.addWidget(add_colons_box) sourcecode_layout.addWidget(close_quotes_box) sourcecode_layout.addWidget(tab_mode_box) sourcecode_layout.addWidget(ibackspace_box) sourcecode_layout.addWidget(removetrail_box) sourcecode_layout.addWidget(strip_mode_box) sourcecode_layout.addLayout(indent_tab_layout) sourcecode_widget = QWidget() sourcecode_widget.setLayout(sourcecode_layout) # --- Run code tab --- saveall_box = newcb(_("Save all files before running script"), 'save_all_before_run') focus_box = newcb( _("Maintain focus in the Editor after running cells " "or selections"), 'focus_to_editor') run_cell_box = newcb( _("Copy full cell contents to the console when " "running code cells"), 'run_cell_copy') run_layout = QVBoxLayout() run_layout.addWidget(saveall_box) run_layout.addWidget(focus_box) run_layout.addWidget(run_cell_box) run_widget = QWidget() run_widget.setLayout(run_layout) # --- Advanced tab --- # -- Templates template_btn = self.create_button(_("Edit template for new files"), self.plugin.edit_template) # -- Autosave autosave_group = QGroupBox(_('Autosave')) autosave_checkbox = newcb( _('Automatically save a copy of files with unsaved changes'), 'autosave_enabled') autosave_spinbox = self.create_spinbox(_('Autosave interval: '), _('seconds'), 'autosave_interval', min_=1, max_=3600) autosave_checkbox.toggled.connect(autosave_spinbox.setEnabled) autosave_layout = QVBoxLayout() autosave_layout.addWidget(autosave_checkbox) autosave_layout.addWidget(autosave_spinbox) autosave_group.setLayout(autosave_layout) # -- Docstring docstring_group = QGroupBox(_('Docstring type')) numpy_url = "<a href='{}'>Numpy</a>".format(NUMPYDOC) googledoc_url = "<a href='{}'>Google</a>".format(GOOGLEDOC) docstring_label = QLabel( _("Here you can select the type of docstrings ({} or {}) you " "want the editor to automatically introduce when pressing " "<tt>{}</tt> after a function/method/class " "declaration.").format(numpy_url, googledoc_url, DOCSTRING_SHORTCUT)) docstring_label.setOpenExternalLinks(True) docstring_label.setWordWrap(True) docstring_combo_choices = ( (_("Numpy"), 'Numpydoc'), (_("Google"), 'Googledoc'), (_("Sphinx"), 'Sphinxdoc'), ) docstring_combo = self.create_combobox(_("Type:"), docstring_combo_choices, 'docstring_type') docstring_layout = QVBoxLayout() docstring_layout.addWidget(docstring_label) docstring_layout.addWidget(docstring_combo) docstring_group.setLayout(docstring_layout) # -- Annotations annotations_group = QGroupBox(_("Annotations")) annotations_label = QLabel( _("Display a marker to the left of line numbers when the " "following annotations appear at the beginning of a comment: " "<tt>TODO, FIXME, XXX, HINT, TIP, @todo, HACK, BUG, OPTIMIZE, " "!!!, ???</tt>")) annotations_label.setWordWrap(True) todolist_box = newcb(_("Display code annotations"), 'todo_list') annotations_layout = QVBoxLayout() annotations_layout.addWidget(annotations_label) annotations_layout.addWidget(todolist_box) annotations_group.setLayout(annotations_layout) # -- EOL eol_group = QGroupBox(_("End-of-line characters")) eol_label = QLabel( _("When opening a text file containing " "mixed end-of-line characters (this may " "raise syntax errors in the consoles " "on Windows platforms), Spyder may fix the " "file automatically.")) eol_label.setWordWrap(True) check_eol_box = newcb(_("Fix automatically and show warning " "message box"), 'check_eol_chars', default=True) convert_eol_on_save_box = newcb(_("On Save: convert EOL characters" " to"), 'convert_eol_on_save', default=False) eol_combo_choices = ( (_("LF (UNIX)"), 'LF'), (_("CRLF (Windows)"), 'CRLF'), (_("CR (Mac)"), 'CR'), ) convert_eol_on_save_combo = self.create_combobox( "", eol_combo_choices, ('convert_eol_on_' 'save_to'), ) convert_eol_on_save_box.toggled.connect( convert_eol_on_save_combo.setEnabled) convert_eol_on_save_combo.setEnabled( self.get_option('convert_eol_on_save')) eol_on_save_layout = QHBoxLayout() eol_on_save_layout.addWidget(convert_eol_on_save_box) eol_on_save_layout.addWidget(convert_eol_on_save_combo) eol_layout = QVBoxLayout() eol_layout.addWidget(eol_label) eol_layout.addWidget(check_eol_box) eol_layout.addLayout(eol_on_save_layout) eol_group.setLayout(eol_layout) # --- Tabs --- tabs = QTabWidget() tabs.addTab(self.create_tab(display_widget), _("Display")) tabs.addTab(self.create_tab(sourcecode_widget), _("Source code")) tabs.addTab(self.create_tab(run_widget), _('Run code')) tabs.addTab( self.create_tab(template_btn, autosave_group, docstring_group, annotations_group, eol_group), _("Advanced settings")) vlayout = QVBoxLayout() vlayout.addWidget(tabs) self.setLayout(vlayout)