def __init__(self, parent, plugin, tabs, data, icon): QDialog.__init__(self, parent) # Variables self.plugins_tabs = [] self.plugins_data = [] self.plugins_instances = [] self.add_plugin(plugin, tabs, data, icon) self.plugin = None # Last plugin with focus self.mode = self.FILE_MODE # By default start in this mode self.initial_cursors = None # {fullpath: QCursor} self.initial_path = None # Fullpath of initial active editor self.initial_widget = None # Initial active editor self.line_number = None # Selected line number in filer self.is_visible = False # Is the switcher visible? help_text = _("Press <b>Enter</b> to switch files or <b>Esc</b> to " "cancel.<br><br>Type to filter filenames.<br><br>" "Use <b>:number</b> to go to a line, e.g. " "<b><code>main:42</code></b><br>" "Use <b>@symbol_text</b> to go to a symbol, e.g. " "<b><code>@init</code></b>" "<br><br> Press <b>Ctrl+W</b> to close current tab.<br>") # Either allow searching for a line number or a symbol but not both regex = QRegExp("([A-Za-z0-9_]{0,100}@[A-Za-z0-9_]{0,100})|" + "([A-Za-z0-9_]{0,100}:{0,1}[0-9]{0,100})") # Widgets self.edit = FilesFilterLine(self) self.help = HelperToolButton() self.list = QListWidget(self) self.filter = KeyPressFilter() regex_validator = QRegExpValidator(regex, self.edit) # Widgets setup self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) self.setWindowOpacity(0.95) self.edit.installEventFilter(self.filter) self.edit.setValidator(regex_validator) self.help.setToolTip(help_text) self.list.setItemDelegate(HTMLDelegate(self)) # Layout edit_layout = QHBoxLayout() edit_layout.addWidget(self.edit) edit_layout.addWidget(self.help) layout = QVBoxLayout() layout.addLayout(edit_layout) layout.addWidget(self.list) self.setLayout(layout) # Signals self.rejected.connect(self.restore_initial_state) self.filter.sig_up_key_pressed.connect(self.previous_row) self.filter.sig_down_key_pressed.connect(self.next_row) self.edit.returnPressed.connect(self.accept) self.edit.textChanged.connect(self.setup) self.list.itemSelectionChanged.connect(self.item_selection_changed) self.list.clicked.connect(self.edit.setFocus)
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 create_controls(self): self.setWindowTitle(tr(self.plugin.name)) vbox = QVBoxLayout() form = QFormLayout() for Name, (enabled, url) in self.packages.items(): name = Name.lower() cbo = QComboBox() if enabled: branches = get_branches(name, url) for n, b in branches.items(): cbo.addItem(n, b) if not check_git_repo(name): cbo.insertItem(0, "<Select to change>", None) cbo.setCurrentIndex(0) self._prev_indices[cbo] = 0 cbo.currentIndexChanged.connect( partial(self._cbo_changed, cbo)) else: cbo.setEditText("<git repository>") cbo.setToolTip(tr( "This is installed in a git repository but we're set to " "not use git.")) cbo.setEnabled(enabled) form.addRow(Name + ':', cbo) vbox.addLayout(form) vbox.addWidget(QLabel(tr( "You should restart the application if you make any changes!"))) btns = QDialogButtonBox(QDialogButtonBox.Ok, Qt.Horizontal, self) btns.accepted.connect(self.accept) vbox.addWidget(btns) self.setLayout(vbox)
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, 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, model): super(AlgorithmMonitorDialog, self).__init__(parent) self.tree = QTreeWidget(self) self.tree.setColumnCount(3) self.tree.setSelectionMode(QTreeWidget.NoSelection) self.tree.setColumnWidth(0, 220) self.tree.setHeaderLabels(['Algorithm', 'Progress', '']) header = self.tree.header() header.setSectionResizeMode(1, QHeaderView.Stretch) header.setSectionResizeMode(2, QHeaderView.Fixed) header.setStretchLastSection(False) button_layout = QHBoxLayout() self.close_button = QPushButton('Close') button_layout.addStretch() button_layout.addWidget(self.close_button) layout = QVBoxLayout() layout.addWidget(self.tree) layout.addLayout(button_layout) self.setLayout(layout) self.setWindowTitle('Mantid - Algorithm progress') self.setWindowIcon(QIcon(":/MantidPlot_Icon_32offset.png")) self.resize(500, 300) self.presenter = AlgorithmProgressDialogPresenter(self, model) self.presenter.update_gui()
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): QDialog.__init__(self, parent) self.setWindowTitle("Spyder %s: %s" % (__version__, _("Dependencies"))) self.setWindowIcon(ima.icon('tooloptions')) self.setModal(True) self.treewidget = DependenciesTreeWidget(self) self.label = QLabel(_("Optional modules are not required to run " "Spyder but enhance its functions.")) self.label2 = QLabel(_("<b>Note:</b> New dependencies or changed ones " "will be correctly detected only after Spyder " "is restarted.")) btn = QPushButton(_("Copy to clipboard"), ) btn.clicked.connect(self.copy_to_clipboard) bbox = QDialogButtonBox(QDialogButtonBox.Ok) bbox.accepted.connect(self.accept) hlayout = QHBoxLayout() hlayout.addWidget(btn) hlayout.addStretch() hlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(self.treewidget) vlayout.addWidget(self.label) vlayout.addWidget(self.label2) vlayout.addLayout(hlayout) self.setLayout(vlayout) self.resize(840, 560)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout)
def __init__(self, *args, **kwargs): super(ClosePackageManagerDialog, self).__init__(*args, **kwargs) self.label_icon = QLabel() self.label_about = QLabel('Conda is still busy.\n\n' 'Do you want to cancel the process?') self.button_ok = QPushButton('Yes') self.button_cancel = QPushButton('No') self.buttonbox = QDialogButtonBox(Qt.Horizontal) # Widget setup self.buttonbox.addButton(self.button_ok, QDialogButtonBox.ActionRole) self.buttonbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole) # self.label_icon.setPixmap(QPixmap(images.ANACONDA_ICON_64_PATH)) self.setWindowTitle("Cancel Process") # Layouts h_layout = QHBoxLayout() h_layout.addWidget(self.label_icon, 0, Qt.AlignTop) h_layout.addSpacing(10) h_layout.addWidget(self.label_about) main_layout = QVBoxLayout() main_layout.addLayout(h_layout) main_layout.addSpacing(20) main_layout.addWidget(self.buttonbox) self.setLayout(main_layout) # Signals self.button_ok.clicked.connect(self.accept) self.button_cancel.clicked.connect(self.reject)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.uid_label = QLabel() self.open_individually_button = QPushButton('Open individually') self.open_individually_button.hide() self.open_individually_button.clicked.connect(self._open_individually) self.open_overplotted_button = QPushButton('Open over-plotted') self.open_overplotted_button.hide() self.open_overplotted_button.clicked.connect(self._open_overplotted) self.open_overplotted_on_button = QPushButton('Add to tab...') self.open_overplotted_on_button.hide() self.open_overplotted_on_button.setEnabled(False) self.open_overplotted_on_button.clicked.connect(self._open_overplotted_on) self.copy_uid_button = QPushButton('Copy UID to Clipboard') self.copy_uid_button.hide() self.copy_uid_button.clicked.connect(self._copy_uid) self.streams = QLabel() self.entries = [] uid_layout = QHBoxLayout() uid_layout.addWidget(self.uid_label) uid_layout.addWidget(self.copy_uid_button) layout = QVBoxLayout() layout.addWidget(self.open_individually_button) layout.addWidget(self.open_overplotted_button) layout.addWidget(self.open_overplotted_on_button) layout.addLayout(uid_layout) layout.addWidget(self.streams) self.setLayout(layout) self._tab_titles = ()
def setup_page(self): # Widgets self.table = ShortcutsTable(self) self.finder = ShortcutFinder(self.table, self.table.set_regex) self.table.finder = self.finder self.label_finder = QLabel(_('Search: ')) self.reset_btn = QPushButton(_("Reset to default values")) # Layout hlayout = QHBoxLayout() vlayout = QVBoxLayout() hlayout.addWidget(self.label_finder) hlayout.addWidget(self.finder) vlayout.addWidget(self.table) vlayout.addLayout(hlayout) vlayout.addWidget(self.reset_btn) self.setLayout(vlayout) self.setTabOrder(self.table, self.finder) self.setTabOrder(self.finder, self.reset_btn) # Signals and slots if PYQT5: # Qt5 'dataChanged' has 3 parameters self.table.proxy_model.dataChanged.connect( lambda i1, i2, roles, opt='': self.has_been_modified(opt)) else: self.table.proxy_model.dataChanged.connect( lambda i1, i2, opt='': self.has_been_modified(opt)) self.reset_btn.clicked.connect(self.reset_to_default)
def __init__(self, plugin, id_, history_filename, config_options, additional_options, interpreter_versions, connection_file=None, hostname=None, menu_actions=None, slave=False, external_kernel=False, given_name=None): super(ClientWidget, self).__init__(plugin) SaveHistoryMixin.__init__(self, history_filename) # --- Init attrs self.id_ = id_ self.connection_file = connection_file self.hostname = hostname self.menu_actions = menu_actions self.slave = slave self.given_name = given_name # --- Other attrs self.options_button = None self.stop_button = None self.stop_icon = ima.icon('stop') self.history = [] self.allow_rename = True self.stderr_dir = None # --- Widgets self.shellwidget = ShellWidget(config=config_options, ipyclient=self, additional_options=additional_options, interpreter_versions=interpreter_versions, external_kernel=external_kernel, local_kernel=True) self.infowidget = WebView(self) self.set_infowidget_font() self.loading_page = self._create_loading_page() self._show_loading_page() # --- Layout vlayout = QVBoxLayout() toolbar_buttons = self.get_toolbar_buttons() hlayout = QHBoxLayout() for button in toolbar_buttons: hlayout.addWidget(button) vlayout.addLayout(hlayout) vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addWidget(self.shellwidget) vlayout.addWidget(self.infowidget) self.setLayout(vlayout) # --- Exit function self.exit_callback = lambda: plugin.close_client(client=self) # --- Signals # As soon as some content is printed in the console, stop # our loading animation document = self.get_control().document() document.contentsChange.connect(self._hide_loading_page) # --- Dialog manager self.dialog_manager = DialogManager()
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 __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.pages_widget.setMinimumWidth(600) self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) self.contents_widget.setMinimumWidth(220) self.contents_widget.setMinimumHeight(400) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) hsplitter.setStretchFactor(0, 1) hsplitter.setStretchFactor(1, 2) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots if self.main: self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, parent): 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 create_controls(self): """ Create UI controls. """ vbox = QVBoxLayout() form = QFormLayout() self.num_angle = QDoubleSpinBox() self.num_angle.setValue(0.0) self.num_angle.setMinimum(-360) self.num_angle.setMaximum(360) form.addRow(tr("Angle:"), self.num_angle) vbox.addLayout(form) self.gbo_preview = QGroupBox(tr("Preview")) self.gbo_preview.setCheckable(True) self.gbo_preview.setChecked(False) gbo_vbox = QVBoxLayout() self.chk_grid = QCheckBox(tr("Grid")) self.chk_grid.setChecked(False) self.num_grid = QSpinBox() self.num_grid.setValue(4) self.num_grid.setMinimum(1) self.num_grid.setEnabled(False) self.chk_grid.toggled[bool].connect(self.num_grid.setEnabled) gbo_vbox.addWidget(self.chk_grid) gbo_vbox.addWidget(self.num_grid) self.gbo_preview.setLayout(gbo_vbox) vbox.addWidget(self.gbo_preview) self.gbo_preview.toggled[bool].connect(self.set_preview) self.gbo_output = QGroupBox(tr("Output")) self.opt_new = QRadioButton(tr("New signal")) self.opt_replace = QRadioButton(tr("In place")) self.opt_new.setChecked(True) gbo_vbox2 = QVBoxLayout() gbo_vbox2.addWidget(self.opt_new) gbo_vbox2.addWidget(self.opt_replace) self.gbo_output.setLayout(gbo_vbox2) vbox.addWidget(self.gbo_output) self.chk_reshape = QCheckBox(tr("Resize to fit")) self.chk_reshape.setChecked(False) vbox.addWidget(self.chk_reshape) self.btn_ok = QPushButton(tr("&OK")) self.btn_ok.setDefault(True) self.btn_ok.clicked.connect(self.accept) self.btn_cancel = QPushButton(tr("&Cancel")) self.btn_cancel.clicked.connect(self.reject) hbox = QHBoxLayout() hbox.addWidget(self.btn_ok) hbox.addWidget(self.btn_cancel) vbox.addLayout(hbox) vbox.addStretch(1) self.setLayout(vbox)
def create_controls(self, path): editor = api.CodeEdit() editor.backend.start(server.__file__) # editor.panels.append(panels.FoldingPanel()) editor.panels.append(panels.LineNumberPanel()) editor.panels.append(panels.CheckerPanel()) editor.modes.append(modes.CaretLineHighlighterMode()) editor.modes.append(modes.CodeCompletionMode()) editor.modes.append(modes.ExtendedSelectionMode()) editor.modes.append(modes.FileWatcherMode()) editor.modes.append(modes.RightMarginMode()) editor.modes.append(modes.SmartBackSpaceMode()) editor.modes.append(modes.OccurrencesHighlighterMode()) editor.modes.append(modes.SymbolMatcherMode()) # editor.modes.append(modes.WordClickMode()) editor.modes.append(modes.ZoomMode()) editor.modes.append(pymodes.PythonSH(editor.document())) editor.modes.append(pymodes.CommentsMode()) editor.modes.append(ConsoleCodeCalltipsMode(self)) editor.modes.append(ConsoleCodeCheckerMode(self)) editor.modes.append(pymodes.PEP8CheckerMode()) editor.modes.append(pymodes.PyAutoCompleteMode()) editor.modes.append(pymodes.PyAutoIndentMode()) editor.modes.append(pymodes.PyIndenterMode()) if path is not None: editor.file._path = path self.editor = editor self.tab = TabWidget(self) if path is not None and os.path.isfile(path): self.tab.add_code_edit(editor) else: self.tab.add_code_edit(editor, tr("untitled") + "%d.py") self.btn_save = QPushButton(tr("Save")) self.btn_run = QPushButton(tr("Run")) self.btn_make_plugin = QPushButton(tr("Make Plugin")) self.btn_reg_plugin = QPushButton(tr("Register Plugin")) self.btn_reg_plugin.setVisible(False) self.btn_save.clicked.connect(self.save) self.btn_run.clicked.connect(self.run) self.btn_make_plugin.clicked.connect(self.make_plugin) self.btn_reg_plugin.clicked.connect(self.register_plugin) self.hbox = QHBoxLayout() for w in [self.btn_save, self.btn_run, self.btn_make_plugin, self.btn_reg_plugin]: self.hbox.addWidget(w) vbox = QVBoxLayout(self) vbox.addWidget(self.tab) vbox.addLayout(self.hbox) self.setLayout(vbox)
def _init_ui(self): self.slit_type_label = QLabel('Slit Type') self.slit_type_combo = QComboBox() self.slit_type_combo.currentIndexChanged.connect(self.update_info) hbl1 = QHBoxLayout() hbl1.addWidget(self.slit_type_label) hbl1.addWidget(self.slit_type_combo) self.slit_width_label = QLabel('Slit Width') self.slit_width_input = QLineEdit() self.slit_width_combo = QComboBox() self.slit_width_units = QLabel('arcsec') hbl2 = QHBoxLayout() hbl2.addWidget(self.slit_width_label) hbl2.addWidget(self.slit_width_input) hbl2.addWidget(self.slit_width_combo) hbl2.addWidget(self.slit_width_units) self.slit_length_label = QLabel('Slit Length') self.slit_length_input = QLineEdit() self.slit_length_combo = QComboBox() self.slit_length_units = QLabel('arcsec') hbl3 = QHBoxLayout() hbl3.addWidget(self.slit_length_label) hbl3.addWidget(self.slit_length_input) hbl3.addWidget(self.slit_length_combo) hbl3.addWidget(self.slit_length_units) self.okButton = QPushButton('Apply') self.okButton.clicked.connect(self.apply) self.okButton.setDefault(True) self.cancelButton = QPushButton('Cancel') self.cancelButton.clicked.connect(self.cancel) hbl4 = QHBoxLayout() hbl4.addWidget(self.cancelButton) hbl4.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) self.setLayout(vbl) self.vbl = vbl self._load_selections() self._populate_combo() self.update_info(0) self.show()
def __init__(self, parent, search_text = r"# ?TODO|# ?FIXME|# ?XXX", search_text_regexp=True, search_path=None, include=[".", ".py"], include_idx=None, include_regexp=True, exclude=r"\.pyc$|\.orig$|\.hg|\.svn", exclude_idx=None, exclude_regexp=True, supported_encodings=("utf-8", "iso-8859-1", "cp1252"), in_python_path=False, more_options=False): QWidget.__init__(self, parent) self.setWindowTitle(_('Find in files')) self.search_thread = None self.get_pythonpath_callback = None self.find_options = FindOptions(self, search_text, search_text_regexp, search_path, include, include_idx, include_regexp, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options) self.find_options.find.connect(self.find) self.find_options.stop.connect(self.stop_and_reset_thread) self.result_browser = ResultsBrowser(self) collapse_btn = create_toolbutton(self) collapse_btn.setDefaultAction(self.result_browser.collapse_all_action) expand_btn = create_toolbutton(self) expand_btn.setDefaultAction(self.result_browser.expand_all_action) restore_btn = create_toolbutton(self) restore_btn.setDefaultAction(self.result_browser.restore_action) # collapse_sel_btn = create_toolbutton(self) # collapse_sel_btn.setDefaultAction( # self.result_browser.collapse_selection_action) # expand_sel_btn = create_toolbutton(self) # expand_sel_btn.setDefaultAction( # self.result_browser.expand_selection_action) btn_layout = QVBoxLayout() btn_layout.setAlignment(Qt.AlignTop) for widget in [collapse_btn, expand_btn, restore_btn]: # collapse_sel_btn, expand_sel_btn]: btn_layout.addWidget(widget) hlayout = QHBoxLayout() hlayout.addWidget(self.result_browser) hlayout.addLayout(btn_layout) layout = QVBoxLayout() left, _x, right, bottom = layout.getContentsMargins() layout.setContentsMargins(left, 0, right, bottom) layout.addWidget(self.find_options) layout.addLayout(hlayout) self.setLayout(layout)
def __init__(self, clasz, parent=None): super().__init__(parent) self.setAccessibleName(" ".join(camelcase_to_words(clasz.__name__))) # Variable self._class = clasz # Layout layout = QVBoxLayout() layout.addLayout(self._init_ui()) # Initialize widgets layout.addStretch() self.setLayout(layout)
def __init__(self, plugin, name, history_filename, config_options, additional_options, interpreter_versions, connection_file=None, hostname=None, menu_actions=None, slave=False): super(ClientWidget, self).__init__(plugin) SaveHistoryMixin.__init__(self) # --- Init attrs self.name = name self.history_filename = get_conf_path(history_filename) self.connection_file = connection_file self.hostname = hostname self.menu_actions = menu_actions self.slave = slave # --- Other attrs self.options_button = None self.stop_button = None self.stop_icon = ima.icon('stop') self.history = [] # --- Widgets self.shellwidget = ShellWidget(config=config_options, additional_options=additional_options, interpreter_versions=interpreter_versions, local_kernel=True) self.shellwidget.hide() self.infowidget = WebView(self) self.set_infowidget_font() self.loading_page = self._create_loading_page() self.infowidget.setHtml(self.loading_page, QUrl.fromLocalFile(CSS_PATH)) # --- Layout vlayout = QVBoxLayout() toolbar_buttons = self.get_toolbar_buttons() hlayout = QHBoxLayout() for button in toolbar_buttons: hlayout.addWidget(button) vlayout.addLayout(hlayout) vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addWidget(self.shellwidget) vlayout.addWidget(self.infowidget) self.setLayout(vlayout) # --- Exit function self.exit_callback = lambda: plugin.close_client(client=self) # --- Signals # As soon as some content is printed in the console, stop # our loading animation document = self.get_control().document() document.contentsChange.connect(self._stop_loading_animation)
def __init__(self, parent=None, pathlist=None, ro_pathlist=None, not_active_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if not_active_pathlist is None: not_active_pathlist = [] self.not_active_pathlist = not_active_pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = getcwd() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(ima.icon('pythonpath')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.listwidget.currentRowChanged.connect(self.refresh) self.listwidget.itemChanged.connect(self.update_not_active_pathlist) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) bbox.rejected.connect(self.reject) bottom_layout.addWidget(bbox) self.update_list() self.refresh()
def setup_page(self): about_label = QLabel(_("The <b>current working directory</b> is " "the working directory for IPython consoles " "and the current directory for the File Explorer.")) about_label.setWordWrap(True) console_group = QGroupBox(_("Console directory")) console_label = QLabel(_("The working directory for new consoles is:")) console_label.setWordWrap(True) console_bg = QButtonGroup(console_group) console_project_radio = self.create_radiobutton( _("The current project directory " "or user home directory " "(if no project is active)"), 'console/use_project_or_home_directory', True, button_group=console_bg) console_cwd_radio = self.create_radiobutton( _("The current working directory"), 'console/use_cwd', False, button_group=console_bg) console_dir_radio = self.create_radiobutton( _("the following directory:"), 'console/use_fixed_directory', False, _("The directory when a new console " "is open will be the specified path"), button_group=console_bg) console_dir_bd = self.create_browsedir("", 'console/fixed_directory', getcwd()) console_dir_radio.toggled.connect(console_dir_bd.setEnabled) console_project_radio.toggled.connect(console_dir_bd.setDisabled) console_cwd_radio.toggled.connect(console_dir_bd.setDisabled) console_dir_layout = QHBoxLayout() console_dir_layout.addWidget(console_dir_radio) console_dir_layout.addWidget(console_dir_bd) console_layout = QVBoxLayout() console_layout.addWidget(console_label) console_layout.addWidget(console_project_radio) console_layout.addWidget(console_cwd_radio) console_layout.addLayout(console_dir_layout) console_group.setLayout(console_layout) vlayout = QVBoxLayout() vlayout.addWidget(about_label) vlayout.addSpacing(10) vlayout.addWidget(console_group) vlayout.addStretch(1) self.setLayout(vlayout)
def __init__(self, parent, search_text=r"# ?TODO|# ?FIXME|# ?XXX", search_text_regexp=True, search_path=None, exclude=r"\.pyc$|\.orig$|\.hg|\.svn", exclude_idx=None, exclude_regexp=True, supported_encodings=("utf-8", "iso-8859-1", "cp1252"), in_python_path=False, more_options=False, case_sensitive=True, external_path_history=[], options_button=None): QWidget.__init__(self, parent) self.setWindowTitle(_('Find in files')) self.search_thread = None self.search_path = '' self.get_pythonpath_callback = None self.status_bar = FileProgressBar(self) self.status_bar.hide() self.find_options = FindOptions(self, search_text, search_text_regexp, search_path, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options, case_sensitive, external_path_history, options_button=options_button) self.find_options.find.connect(self.find) self.find_options.stop.connect(self.stop_and_reset_thread) self.result_browser = ResultsBrowser(self) hlayout = QHBoxLayout() hlayout.addWidget(self.result_browser) layout = QVBoxLayout() left, _x, right, bottom = layout.getContentsMargins() layout.setContentsMargins(left, 0, right, bottom) layout.addWidget(self.find_options) layout.addLayout(hlayout) layout.addWidget(self.status_bar) self.setLayout(layout)
def _init_ui(self): # Widgets self._txt_x = NumericalAttributeLineEdit(self._class.x) self._txt_y = NumericalAttributeLineEdit(self._class.y) self._txt_z = NumericalAttributeLineEdit(self._class.z) self._txt_r = NumericalAttributeLineEdit(self._class.r) self._txt_t = NumericalAttributeLineEdit(self._class.t) # Layouts if self._inline: layout = QVBoxLayout() layout_xyz = QHBoxLayout() layout_xyz.addWidget(QLabel('X')) layout_xyz.addWidget(self._txt_x) layout_xyz.addWidget(QLabel('Y')) layout_xyz.addWidget(self._txt_y) layout_xyz.addWidget(QLabel('Z')) layout_xyz.addWidget(self._txt_z) layout_rt = QHBoxLayout() layout_rt.addWidget(QLabel('R')) layout_rt.addWidget(self._txt_r) layout_rt.addWidget(QLabel('T')) layout_rt.addWidget(self._txt_t) layout.addLayout(layout_xyz) layout.addLayout(layout_rt) else: layout = _ConditionWidget._init_ui(self) layout.addRow('X', self._txt_x) layout.addRow('Y', self._txt_y) layout.addRow('Z', self._txt_z) layout.addRow('R', self._txt_r) layout.addRow('T', self._txt_t) # Signals self._txt_x.textEdited.connect(self.edited) self._txt_y.textEdited.connect(self.edited) self._txt_z.textEdited.connect(self.edited) self._txt_r.textEdited.connect(self.edited) self._txt_t.textEdited.connect(self.edited) return layout
def __init__(self, plugin, name, history_filename, connection_file=None, hostname=None, sshkey=None, password=None, kernel_widget_id=None, menu_actions=None): super(IPythonClient, self).__init__(plugin) SaveHistoryMixin.__init__(self) self.options_button = None # stop button and icon self.stop_button = None self.stop_icon = ima.icon('stop') self.connection_file = connection_file self.kernel_widget_id = kernel_widget_id self.hostname = hostname self.sshkey = sshkey self.password = password self.name = name self.get_option = plugin.get_option self.shellwidget = IPythonShellWidget(config=self.shellwidget_config(), local_kernel=False) self.shellwidget.hide() self.infowidget = WebView(self) self.menu_actions = menu_actions self.history_filename = get_conf_path(history_filename) self.history = [] self.namespacebrowser = None self.set_infowidget_font() self.loading_page = self._create_loading_page() self.infowidget.setHtml(self.loading_page, QUrl.fromLocalFile(CSS_PATH)) vlayout = QVBoxLayout() toolbar_buttons = self.get_toolbar_buttons() hlayout = QHBoxLayout() for button in toolbar_buttons: hlayout.addWidget(button) vlayout.addLayout(hlayout) vlayout.setContentsMargins(0, 0, 0, 0) vlayout.addWidget(self.shellwidget) vlayout.addWidget(self.infowidget) self.setLayout(vlayout) self.exit_callback = lambda: plugin.close_client(client=self)
def setup_widgets_for_orientation(self, new_orientation): """ Reconstruct the widget given the orientation. Parameters ---------- new_orientation : int Qt.Horizontal or Qt.Vertical """ if new_orientation not in (Qt.Horizontal, Qt.Vertical): logger.error("Invalid orientation '{0}'. The existing layout will not change.".format(new_orientation)) return layout = None if new_orientation == Qt.Horizontal: layout = QVBoxLayout() layout.setContentsMargins(4, 0, 4, 4) label_layout = QHBoxLayout() label_layout.addWidget(self.low_lim_label) label_layout.addStretch(0) label_layout.addWidget(self.value_label) label_layout.addStretch(0) label_layout.addWidget(self.high_lim_label) layout.addLayout(label_layout) self._slider.setOrientation(new_orientation) layout.addWidget(self._slider) elif new_orientation == Qt.Vertical: layout = QHBoxLayout() layout.setContentsMargins(0, 4, 4, 4) label_layout = QVBoxLayout() label_layout.addWidget(self.high_lim_label) label_layout.addStretch(0) label_layout.addWidget(self.value_label) label_layout.addStretch(0) label_layout.addWidget(self.low_lim_label) layout.addLayout(label_layout) self._slider.setOrientation(new_orientation) layout.addWidget(self._slider) if self.layout() is not None: # Trick to remove the existing layout by re-parenting it in an empty widget. QWidget().setLayout(self.layout()) self.setLayout(layout)
def __init__(self, clasz, controller, datum=None, parent=None): QWidget.__init__(self, parent) name = clasz.TEMPLATE if clasz.CLASS is not None: name += ' (%s)' % clasz.CLASS self.setAccessibleName(name) # Variables self._class = clasz self._controller = controller # Layouts layout = QVBoxLayout() layout.addLayout(self._init_ui()) # Initialize widgets self.setLayout(layout) # Defaults self.setDatum(datum)
def __init__(self, parent): QDialog.__init__(self, parent) self.setWindowTitle("Spyder %s: %s" % (__version__, _("Dependencies"))) self.setWindowIcon(ima.icon('tooloptions')) self.setModal(True) self.view = DependenciesTableView(self, []) opt_mods = ['NumPy', 'Matplotlib', 'Pandas', 'SymPy'] self.label = QLabel(_("Spyder depends on several Python modules to " "provide the right functionality for all its " "panes. The table below shows the required " "and installed versions (if any) of all of " "them.<br><br>" "<b>Note</b>: You can safely use Spyder " "without the following modules installed: " "<b>%s</b> and <b>%s</b>.<br><br>" "Please also note that new " "dependencies or changed ones will be correctly " "detected only after Spyder is restarted.") % (', '.join(opt_mods[:-1]), opt_mods[-1])) self.label.setWordWrap(True) self.label.setAlignment(Qt.AlignJustify) self.label.setContentsMargins(5, 8, 12, 10) btn = QPushButton(_("Copy to clipboard"), ) btn.clicked.connect(self.copy_to_clipboard) bbox = QDialogButtonBox(QDialogButtonBox.Ok) bbox.accepted.connect(self.accept) hlayout = QHBoxLayout() hlayout.addWidget(btn) hlayout.addStretch() hlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(self.label) vlayout.addWidget(self.view) vlayout.addLayout(hlayout) self.setLayout(vlayout) self.resize(630, 420)
def setup_page(self): about_label = QLabel(_("The <b>global working directory</b> is " "the working directory for newly opened <i>consoles</i> " "(Python/IPython consoles and terminals), for the " "<i>file explorer</i>, for the <i>find in files</i> " "plugin and for new files created in the <i>editor</i>.")) about_label.setWordWrap(True) startup_group = QGroupBox(_("Startup")) startup_bg = QButtonGroup(startup_group) startup_label = QLabel(_("At startup, the global working " "directory is:")) startup_label.setWordWrap(True) lastdir_radio = self.create_radiobutton( _("the same as in last session"), 'startup/use_last_directory', True, _("At startup, Spyder will restore the " "global directory from last session"), button_group=startup_bg) thisdir_radio = self.create_radiobutton( _("the following directory:"), 'startup/use_fixed_directory', False, _("At startup, the global working " "directory will be the specified path"), button_group=startup_bg) thisdir_bd = self.create_browsedir("", 'startup/fixed_directory', getcwd()) thisdir_radio.toggled.connect(thisdir_bd.setEnabled) lastdir_radio.toggled.connect(thisdir_bd.setDisabled) thisdir_layout = QHBoxLayout() thisdir_layout.addWidget(thisdir_radio) thisdir_layout.addWidget(thisdir_bd) editor_o_group = QGroupBox(_("Open file")) editor_o_label = QLabel(_("Files are opened from:")) editor_o_label.setWordWrap(True) editor_o_bg = QButtonGroup(editor_o_group) editor_o_radio1 = self.create_radiobutton( _("the current file directory"), 'editor/open/browse_scriptdir', button_group=editor_o_bg) editor_o_radio2 = self.create_radiobutton( _("the global working directory"), 'editor/open/browse_workdir', button_group=editor_o_bg) editor_n_group = QGroupBox(_("New file")) editor_n_label = QLabel(_("Files are created in:")) editor_n_label.setWordWrap(True) editor_n_bg = QButtonGroup(editor_n_group) editor_n_radio1 = self.create_radiobutton( _("the current file directory"), 'editor/new/browse_scriptdir', button_group=editor_n_bg) editor_n_radio2 = self.create_radiobutton( _("the global working directory"), 'editor/new/browse_workdir', button_group=editor_n_bg) # Note: default values for the options above are set in plugin's # constructor (see below) other_group = QGroupBox(_("Change to file base directory")) newcb = self.create_checkbox open_box = newcb(_("When opening a file"), 'editor/open/auto_set_to_basedir') save_box = newcb(_("When saving a file"), 'editor/save/auto_set_to_basedir') startup_layout = QVBoxLayout() startup_layout.addWidget(startup_label) startup_layout.addWidget(lastdir_radio) startup_layout.addLayout(thisdir_layout) startup_group.setLayout(startup_layout) editor_o_layout = QVBoxLayout() editor_o_layout.addWidget(editor_o_label) editor_o_layout.addWidget(editor_o_radio1) editor_o_layout.addWidget(editor_o_radio2) editor_o_group.setLayout(editor_o_layout) editor_n_layout = QVBoxLayout() editor_n_layout.addWidget(editor_n_label) editor_n_layout.addWidget(editor_n_radio1) editor_n_layout.addWidget(editor_n_radio2) editor_n_group.setLayout(editor_n_layout) other_layout = QVBoxLayout() other_layout.addWidget(open_box) other_layout.addWidget(save_box) other_group.setLayout(other_layout) vlayout = QVBoxLayout() vlayout.addWidget(about_label) vlayout.addSpacing(10) vlayout.addWidget(startup_group) vlayout.addWidget(editor_o_group) vlayout.addWidget(editor_n_group) vlayout.addWidget(other_group) vlayout.addStretch(1) self.setLayout(vlayout)
def __init__(self, settings: PartSettings): super().__init__() self.settings = settings self.save_translate_dict: typing.Dict[str, SaveBase] = { x.get_short_name(): x for x in save_dict.values() } self.plan = PlanPreview(self) self.save_plan_btn = QPushButton("Save") self.clean_plan_btn = QPushButton("Remove all") self.remove_btn = QPushButton("Remove") self.update_element_chk = QCheckBox("Update element") self.change_root = EnumComboBox(RootType) self.save_choose = QComboBox() self.save_choose.addItem("<none>") self.save_choose.addItems(list(self.save_translate_dict.keys())) self.save_btn = QPushButton("Save") self.segment_profile = QListWidget() self.pipeline_profile = QListWidget() self.segment_stack = QTabWidget() self.segment_stack.addTab(self.segment_profile, "Profile") self.segment_stack.addTab(self.pipeline_profile, "Pipeline") self.generate_mask_btn = QPushButton("Add mask") self.generate_mask_btn.setToolTip("Mask need to have unique name") self.mask_name = QLineEdit() self.mask_operation = EnumComboBox(MaskOperation) self.chanel_num = QSpinBox() self.choose_channel_for_measurements = QComboBox() self.choose_channel_for_measurements.addItems( ["Same as segmentation"] + [str(x + 1) for x in range(MAX_CHANNEL_NUM)]) self.units_choose = EnumComboBox(Units) self.units_choose.set_value(self.settings.get("units_value", Units.nm)) self.chanel_num.setRange(0, 10) self.expected_node_type = None self.save_constructor = None self.chose_profile_btn = QPushButton("Add Profile") self.get_big_btn = QPushButton("Leave the biggest") self.get_big_btn.hide() self.add_new_segmentation_btn = QPushButton("Add new profile") self.get_big_btn.setDisabled(True) self.add_new_segmentation_btn.setDisabled(True) self.measurements_list = QListWidget(self) self.measurement_name_prefix = QLineEdit(self) self.add_calculation_btn = QPushButton("Add measurement calculation") self.information = QTextEdit() self.information.setReadOnly(True) self.protect = False self.mask_set = set() self.calculation_plan = CalculationPlan() self.plan.set_plan(self.calculation_plan) self.segmentation_mask = MaskWidget(settings) self.file_mask = FileMask() self.change_root.currentIndexChanged.connect(self.change_root_type) self.save_choose.currentTextChanged.connect(self.save_changed) self.measurements_list.currentTextChanged.connect( self.show_measurement) self.segment_profile.currentTextChanged.connect(self.show_segment) self.measurements_list.currentTextChanged.connect( self.show_measurement_info) self.segment_profile.currentTextChanged.connect(self.show_segment_info) self.pipeline_profile.currentTextChanged.connect( self.show_segment_info) self.pipeline_profile.currentTextChanged.connect(self.show_segment) self.mask_name.textChanged.connect(self.mask_name_changed) self.generate_mask_btn.clicked.connect(self.create_mask) self.clean_plan_btn.clicked.connect(self.clean_plan) self.remove_btn.clicked.connect(self.remove_element) self.mask_name.textChanged.connect(self.mask_text_changed) self.chose_profile_btn.clicked.connect(self.add_segmentation) self.get_big_btn.clicked.connect(self.add_leave_biggest) self.add_calculation_btn.clicked.connect(self.add_measurement) self.save_plan_btn.clicked.connect(self.add_calculation_plan) # self.forgot_mask_btn.clicked.connect(self.forgot_mask) # self.cmap_save_btn.clicked.connect(self.save_to_cmap) self.save_btn.clicked.connect(self.add_save_to_project) self.update_element_chk.stateChanged.connect(self.mask_text_changed) self.update_element_chk.stateChanged.connect(self.show_measurement) self.update_element_chk.stateChanged.connect(self.show_segment) self.update_element_chk.stateChanged.connect(self.update_names) self.segment_stack.currentChanged.connect( self.change_segmentation_table) plan_box = QGroupBox("Prepare workflow:") lay = QVBoxLayout() lay.addWidget(self.plan) bt_lay = QGridLayout() bt_lay.setSpacing(0) bt_lay.addWidget(self.save_plan_btn, 0, 0) bt_lay.addWidget(self.clean_plan_btn, 0, 1) bt_lay.addWidget(self.remove_btn, 1, 0) bt_lay.addWidget(self.update_element_chk, 1, 1) lay.addLayout(bt_lay) plan_box.setLayout(lay) plan_box.setStyleSheet(group_sheet) other_box = QGroupBox("Other operations:") other_box.setContentsMargins(0, 0, 0, 0) bt_lay = QVBoxLayout() bt_lay.setSpacing(0) bt_lay.addWidget(QLabel("Root type:")) bt_lay.addWidget(self.change_root) bt_lay.addStretch(1) bt_lay.addWidget(QLabel("Saving:")) bt_lay.addWidget(self.save_choose) bt_lay.addWidget(self.save_btn) other_box.setLayout(bt_lay) other_box.setStyleSheet(group_sheet) mask_box = QGroupBox("Use mask from:") mask_box.setStyleSheet(group_sheet) self.mask_stack = QTabWidget() self.mask_stack.addTab(stretch_widget(self.file_mask), "File") self.mask_stack.addTab(stretch_widget(self.segmentation_mask), "Current segmentation") self.mask_stack.addTab(stretch_widget(self.mask_operation), "Operations on masks") self.mask_stack.setTabToolTip( 2, "Allows to create mask which is based on masks previously added to plan." ) lay = QGridLayout() lay.setSpacing(0) lay.addWidget(self.mask_stack, 0, 0, 1, 2) label = QLabel("Mask name:") label.setToolTip( "Needed if you would like to reuse this mask in tab 'Operations on masks'" ) self.mask_name.setToolTip( "Needed if you would like to reuse this mask in tab 'Operations on masks'" ) lay.addWidget(label, 1, 0) lay.addWidget(self.mask_name, 1, 1) lay.addWidget(self.generate_mask_btn, 2, 0, 1, 2) mask_box.setLayout(lay) segment_box = QGroupBox("Segmentation:") segment_box.setStyleSheet(group_sheet) lay = QVBoxLayout() lay.setSpacing(0) lay.addWidget(self.segment_stack) lay.addWidget(self.chose_profile_btn) lay.addWidget(self.get_big_btn) lay.addWidget(self.add_new_segmentation_btn) segment_box.setLayout(lay) measurement_box = QGroupBox("Set of measurements:") measurement_box.setStyleSheet(group_sheet) lay = QGridLayout() lay.setSpacing(0) lay.addWidget(self.measurements_list, 0, 0, 1, 2) lab = QLabel("Name prefix:") lab.setToolTip("Prefix added before each column name") lay.addWidget(lab, 1, 0) lay.addWidget(self.measurement_name_prefix, 1, 1) lay.addWidget(QLabel("Channel:"), 2, 0) lay.addWidget(self.choose_channel_for_measurements, 2, 1) lay.addWidget(QLabel("Units:")) lay.addWidget(self.units_choose, 3, 1) lay.addWidget(self.add_calculation_btn, 4, 0, 1, 2) measurement_box.setLayout(lay) info_box = QGroupBox("Information") info_box.setStyleSheet(group_sheet) lay = QVBoxLayout() lay.addWidget(self.information) info_box.setLayout(lay) layout = QGridLayout() fst_col = QVBoxLayout() fst_col.addWidget(plan_box, 1) fst_col.addWidget(mask_box) layout.addWidget(plan_box, 0, 0, 5, 1) # layout.addWidget(plan_box, 0, 0, 3, 1) # layout.addWidget(mask_box, 3, 0, 2, 1) # layout.addWidget(segmentation_mask_box, 1, 1) layout.addWidget(mask_box, 0, 2, 1, 2) layout.addWidget(other_box, 0, 1) layout.addWidget(segment_box, 1, 1, 1, 2) layout.addWidget(measurement_box, 1, 3) layout.addWidget(info_box, 3, 1, 1, 3) self.setLayout(layout) self.generate_mask_btn.setDisabled(True) self.chose_profile_btn.setDisabled(True) self.add_calculation_btn.setDisabled(True) self.mask_allow = False self.segment_allow = False self.file_mask_allow = False self.node_type = NodeType.root self.node_name = "" self.plan_node_changed.connect(self.mask_text_changed) self.plan.changed_node.connect(self.node_type_changed) self.plan_node_changed.connect(self.show_segment) self.plan_node_changed.connect(self.show_measurement) self.plan_node_changed.connect(self.mask_stack_change) self.mask_stack.currentChanged.connect(self.mask_stack_change) self.file_mask.value_changed.connect(self.mask_stack_change) self.mask_name.textChanged.connect(self.mask_stack_change) self.node_type_changed()
def __init__(self, parent=None, is_report=False): QDialog.__init__(self, parent) self.is_report = is_report self.setWindowTitle(_("Issue reporter")) self.setModal(True) # To save the traceback sent to the internal console self.error_traceback = "" # Dialog main label if self.is_report: title = _("Please fill the following information") else: title = _("Spyder has encountered an internal problem!") main_label = QLabel( _("<h3>{title}</h3>" "Before reporting this problem, <i>please</i> consult our " "comprehensive " "<b><a href=\"{trouble_url}\">Troubleshooting Guide</a></b> " "which should help solve most issues, and search for " "<b><a href=\"{project_url}\">known bugs</a></b> " "matching your error message or problem description for a " "quicker solution.").format(title=title, trouble_url=__trouble_url__, project_url=__project_url__)) main_label.setOpenExternalLinks(True) main_label.setWordWrap(True) main_label.setAlignment(Qt.AlignJustify) main_label.setStyleSheet('font-size: 12px;') # Issue title self.title = QLineEdit() self.title.textChanged.connect(self._contents_changed) self.title_chars_label = QLabel( _("{} more characters " "to go...").format(TITLE_MIN_CHARS)) form_layout = QFormLayout() red_asterisk = '<font color="Red">*</font>' title_label = QLabel(_("<b>Title</b>: {}").format(red_asterisk)) form_layout.setWidget(0, QFormLayout.LabelRole, title_label) form_layout.setWidget(0, QFormLayout.FieldRole, self.title) # Description steps_header = QLabel( _("<b>Steps to reproduce:</b> {}").format(red_asterisk)) steps_text = QLabel( _("Please enter a detailed step-by-step " "description (in English) of what led up to " "the problem below. Issue reports without a " "clear way to reproduce them will be closed.")) steps_text.setWordWrap(True) steps_text.setAlignment(Qt.AlignJustify) steps_text.setStyleSheet('font-size: 12px;') # Field to input the description of the problem self.input_description = DescriptionWidget(self) # Only allow to submit to Github if we have a long enough description self.input_description.textChanged.connect(self._contents_changed) # Widget to show errors self.details = ShowErrorWidget(self) self.details.set_pythonshell_font(get_font()) self.details.hide() # Label to show missing chars self.initial_chars = len(self.input_description.toPlainText()) self.desc_chars_label = QLabel( _("{} more characters " "to go...").format(DESC_MIN_CHARS)) # Checkbox to dismiss future errors self.dismiss_box = QCheckBox( _("Hide all future errors during this " "session")) if self.is_report: self.dismiss_box.hide() # Dialog buttons gh_icon = ima.icon('github') self.submit_btn = QPushButton(gh_icon, _('Submit to Github')) self.submit_btn.setEnabled(False) self.submit_btn.clicked.connect(self._submit_to_github) self.details_btn = QPushButton(_('Show details')) self.details_btn.clicked.connect(self._show_details) if self.is_report: self.details_btn.hide() self.close_btn = QPushButton(_('Close')) if self.is_report: self.close_btn.clicked.connect(self.reject) # Buttons layout buttons_layout = QHBoxLayout() buttons_layout.addWidget(self.submit_btn) buttons_layout.addWidget(self.details_btn) buttons_layout.addWidget(self.close_btn) # Main layout layout = QVBoxLayout() layout.addWidget(main_label) layout.addSpacing(20) layout.addLayout(form_layout) layout.addWidget(self.title_chars_label) layout.addSpacing(12) layout.addWidget(steps_header) layout.addSpacing(-1) layout.addWidget(steps_text) layout.addSpacing(1) layout.addWidget(self.input_description) layout.addWidget(self.details) layout.addWidget(self.desc_chars_label) layout.addSpacing(15) layout.addWidget(self.dismiss_box) layout.addSpacing(15) layout.addLayout(buttons_layout) layout.setContentsMargins(25, 20, 25, 10) self.setLayout(layout) self.resize(570, 600) self.title.setFocus() # Set Tab key focus order self.setTabOrder(self.title, self.input_description)
def __init__( self, plugin_manager: PluginManager = napari_plugin_manager, *, parent: Optional[QWidget] = None, initial_hook: Optional[str] = None, firstresult_only: bool = True, ): super().__init__(parent) self.plugin_manager = plugin_manager self.hook_combo_box = QComboBox() self.hook_combo_box.addItem(self.NULL_OPTION, None) # populate comboBox with all of the hooks known by the plugin manager for name, hook_caller in plugin_manager.hooks.items(): # only show hooks with specifications if not hook_caller.spec: continue if firstresult_only: # if the firstresult_only option is set # we only want to include hook_specifications that declare the # "firstresult" option as True. if not hook_caller.spec.opts.get('firstresult', False): continue self.hook_combo_box.addItem(name.replace("napari_", ""), hook_caller) self.plugin_manager.events.disabled.connect(self._on_disabled) self.plugin_manager.events.registered.connect(self.refresh) self.hook_combo_box.setToolTip( trans._("select the hook specification to reorder")) self.hook_combo_box.currentIndexChanged.connect(self._on_hook_change) self.hook_list = QtHookImplementationListWidget(parent=self) self.hook_list.order_changed.connect(self._change_settings_plugins) self.hook_list.on_changed.connect(self._change_settings_plugins) instructions = QLabel( trans. _('Select a hook to rearrange, then drag and drop plugins into the desired call order.\n\nDisable plugins for a specific hook by unchecking their checkbox.' )) instructions.setWordWrap(True) self.docstring = QLabel(self) self.info = QtToolTipLabel(self) self.info.setObjectName("info_icon") doc_lay = QHBoxLayout() doc_lay.addWidget(self.docstring) doc_lay.setStretch(0, 1) doc_lay.addWidget(self.info) self.docstring.setWordWrap(True) self.docstring.setObjectName('small_text') self.info.hide() self.docstring.hide() layout = QVBoxLayout(self) layout.addWidget(instructions) layout.addWidget(self.hook_combo_box) layout.addLayout(doc_lay) layout.addWidget(self.hook_list) if initial_hook is not None: self.set_hookname(initial_hook)
class ClientWidget(QWidget, SaveHistoryMixin): """ Client widget for the IPython Console This widget is necessary to handle the interaction between the plugin and each shell widget. """ SEPARATOR = '{0}## ---({1})---'.format(os.linesep * 2, time.ctime()) INITHISTORY = [ '# -*- coding: utf-8 -*-', '# *** Spyder Python Console History Log ***', ] append_to_history = Signal(str, str) def __init__(self, plugin, id_, history_filename, config_options, additional_options, interpreter_versions, connection_file=None, hostname=None, menu_actions=None, slave=False, external_kernel=False, given_name=None, options_button=None, show_elapsed_time=False, reset_warning=True, ask_before_restart=True, css_path=None): super(ClientWidget, self).__init__(plugin) SaveHistoryMixin.__init__(self, history_filename) # --- Init attrs self.id_ = id_ self.connection_file = connection_file self.hostname = hostname self.menu_actions = menu_actions self.slave = slave self.external_kernel = external_kernel self.given_name = given_name self.show_elapsed_time = show_elapsed_time self.reset_warning = reset_warning self.ask_before_restart = ask_before_restart # --- Other attrs self.options_button = options_button self.stop_button = None self.reset_button = None self.stop_icon = ima.icon('stop') self.history = [] self.allow_rename = True self.stderr_dir = None self.is_error_shown = False if css_path is None: self.css_path = CSS_PATH else: self.css_path = css_path # --- Widgets self.shellwidget = ShellWidget( config=config_options, ipyclient=self, additional_options=additional_options, interpreter_versions=interpreter_versions, external_kernel=external_kernel, local_kernel=True) self.infowidget = plugin.infowidget self.blank_page = self._create_blank_page() self.loading_page = self._create_loading_page() # To keep a reference to the page to be displayed # in infowidget self.info_page = None self._show_loading_page() # Elapsed time self.time_label = None self.t0 = time.monotonic() self.timer = QTimer(self) self.show_time_action = create_action( self, _("Show elapsed time"), toggled=self.set_elapsed_time_visible) # --- Layout self.layout = QVBoxLayout() toolbar_buttons = self.get_toolbar_buttons() hlayout = QHBoxLayout() hlayout.addWidget(self.create_time_label()) hlayout.addStretch(0) for button in toolbar_buttons: hlayout.addWidget(button) self.layout.addLayout(hlayout) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.shellwidget) self.layout.addWidget(self.infowidget) self.setLayout(self.layout) # --- Exit function self.exit_callback = lambda: plugin.close_client(client=self) # --- Dialog manager self.dialog_manager = DialogManager() # Show timer self.update_time_label_visibility() #------ Public API -------------------------------------------------------- @property def kernel_id(self): """Get kernel id""" if self.connection_file is not None: json_file = osp.basename(self.connection_file) return json_file.split('.json')[0] @property def stderr_file(self): """Filename to save kernel stderr output.""" stderr_file = None if self.connection_file is not None: stderr_file = self.kernel_id + '.stderr' if self.stderr_dir is not None: stderr_file = osp.join(self.stderr_dir, stderr_file) else: try: stderr_file = osp.join(get_temp_dir(), stderr_file) except (IOError, OSError): stderr_file = None return stderr_file @property def stderr_handle(self): """Get handle to stderr_file.""" if self.stderr_file is not None: # Needed to prevent any error that could appear. # See issue 6267 try: handle = codecs.open(self.stderr_file, 'w', encoding='utf-8') except Exception: handle = None else: handle = None return handle def remove_stderr_file(self): """Remove stderr_file associated with the client.""" try: # Defer closing the stderr_handle until the client # is closed because jupyter_client needs it open # while it tries to restart the kernel self.stderr_handle.close() os.remove(self.stderr_file) except Exception: pass def configure_shellwidget(self, give_focus=True): """Configure shellwidget after kernel is started""" if give_focus: self.get_control().setFocus() # Set exit callback self.shellwidget.set_exit_callback() # To save history self.shellwidget.executing.connect(self.add_to_history) # For Mayavi to run correctly self.shellwidget.executing.connect( self.shellwidget.set_backend_for_mayavi) # To update history after execution self.shellwidget.executed.connect(self.update_history) # To update the Variable Explorer after execution self.shellwidget.executed.connect( self.shellwidget.refresh_namespacebrowser) # To enable the stop button when executing a process self.shellwidget.executing.connect(self.enable_stop_button) # To disable the stop button after execution stopped self.shellwidget.executed.connect(self.disable_stop_button) # To show kernel restarted/died messages self.shellwidget.sig_kernel_restarted.connect( self.kernel_restarted_message) # To correctly change Matplotlib backend interactively self.shellwidget.executing.connect(self.shellwidget.change_mpl_backend) # To show env and sys.path contents self.shellwidget.sig_show_syspath.connect(self.show_syspath) self.shellwidget.sig_show_env.connect(self.show_env) # To sync with working directory toolbar self.shellwidget.executed.connect(self.shellwidget.get_cwd) # To apply style self.set_color_scheme(self.shellwidget.syntax_style, reset=False) # To hide the loading page self.shellwidget.sig_prompt_ready.connect(self._hide_loading_page) # Show possible errors when setting Matplotlib backend self.shellwidget.sig_prompt_ready.connect( self._show_mpl_backend_errors) def enable_stop_button(self): self.stop_button.setEnabled(True) def disable_stop_button(self): # This avoids disabling automatically the button when # re-running files on dedicated consoles. # See issue #5958 if not self.shellwidget._executing: self.stop_button.setDisabled(True) @Slot() def stop_button_click_handler(self): """Method to handle what to do when the stop button is pressed""" self.stop_button.setDisabled(True) # Interrupt computations or stop debugging if not self.shellwidget._reading: self.interrupt_kernel() else: self.shellwidget.write_to_stdin('exit') def show_kernel_error(self, error): """Show kernel initialization errors in infowidget.""" # Replace end of line chars with <br> eol = sourcecode.get_eol_chars(error) if eol: error = error.replace(eol, '<br>') # Don't break lines in hyphens # From https://stackoverflow.com/q/7691569/438386 error = error.replace('-', '‑') # Create error page message = _("An error ocurred while starting the kernel") kernel_error_template = Template(KERNEL_ERROR) self.info_page = kernel_error_template.substitute( css_path=self.css_path, message=message, error=error) # Show error self.set_info_page() self.shellwidget.hide() self.infowidget.show() # Tell the client we're in error mode self.is_error_shown = True def get_name(self): """Return client name""" if self.given_name is None: # Name according to host if self.hostname is None: name = _("Console") else: name = self.hostname # Adding id to name client_id = self.id_['int_id'] + u'/' + self.id_['str_id'] name = name + u' ' + client_id elif self.given_name in ["Pylab", "SymPy", "Cython"]: client_id = self.id_['int_id'] + u'/' + self.id_['str_id'] name = self.given_name + u' ' + client_id else: name = self.given_name + u'/' + self.id_['str_id'] return name def get_control(self): """Return the text widget (or similar) to give focus to""" # page_control is the widget used for paging page_control = self.shellwidget._page_control if page_control and page_control.isVisible(): return page_control else: return self.shellwidget._control def get_kernel(self): """Get kernel associated with this client""" return self.shellwidget.kernel_manager def get_options_menu(self): """Return options menu""" env_action = create_action(self, _("Show environment variables"), icon=ima.icon('environ'), triggered=self.shellwidget.get_env) syspath_action = create_action(self, _("Show sys.path contents"), icon=ima.icon('syspath'), triggered=self.shellwidget.get_syspath) self.show_time_action.setChecked(self.show_elapsed_time) additional_actions = [ MENU_SEPARATOR, env_action, syspath_action, self.show_time_action ] if self.menu_actions is not None: console_menu = self.menu_actions + additional_actions return console_menu else: return additional_actions def get_toolbar_buttons(self): """Return toolbar buttons list.""" buttons = [] # Code to add the stop button if self.stop_button is None: self.stop_button = create_toolbutton( self, text=_("Stop"), icon=self.stop_icon, tip=_("Stop the current command")) self.disable_stop_button() # set click event handler self.stop_button.clicked.connect(self.stop_button_click_handler) if is_dark_interface(): self.stop_button.setStyleSheet("QToolButton{padding: 3px;}") if self.stop_button is not None: buttons.append(self.stop_button) # Reset namespace button if self.reset_button is None: self.reset_button = create_toolbutton( self, text=_("Remove"), icon=ima.icon('editdelete'), tip=_("Remove all variables"), triggered=self.reset_namespace) if is_dark_interface(): self.reset_button.setStyleSheet("QToolButton{padding: 3px;}") if self.reset_button is not None: buttons.append(self.reset_button) if self.options_button is None: options = self.get_options_menu() if options: self.options_button = create_toolbutton( self, text=_('Options'), icon=ima.icon('tooloptions')) self.options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) add_actions(menu, options) self.options_button.setMenu(menu) if self.options_button is not None: buttons.append(self.options_button) return buttons def add_actions_to_context_menu(self, menu): """Add actions to IPython widget context menu""" inspect_action = create_action( self, _("Inspect current object"), QKeySequence(get_shortcut('console', 'inspect current object')), icon=ima.icon('MessageBoxInformation'), triggered=self.inspect_object) clear_line_action = create_action( self, _("Clear line or block"), QKeySequence(get_shortcut('console', 'clear line')), triggered=self.clear_line) reset_namespace_action = create_action( self, _("Remove all variables"), QKeySequence(get_shortcut('ipython_console', 'reset namespace')), icon=ima.icon('editdelete'), triggered=self.reset_namespace) clear_console_action = create_action( self, _("Clear console"), QKeySequence(get_shortcut('console', 'clear shell')), triggered=self.clear_console) quit_action = create_action(self, _("&Quit"), icon=ima.icon('exit'), triggered=self.exit_callback) add_actions( menu, (None, inspect_action, clear_line_action, clear_console_action, reset_namespace_action, None, quit_action)) return menu def set_font(self, font): """Set IPython widget's font""" self.shellwidget._control.setFont(font) self.shellwidget.font = font def set_color_scheme(self, color_scheme, reset=True): """Set IPython color scheme.""" # Needed to handle not initialized kernel_client # See issue 6996 try: self.shellwidget.set_color_scheme(color_scheme, reset) except AttributeError: pass def shutdown(self): """Shutdown kernel""" if self.get_kernel() is not None and not self.slave: now = True # This avoids some flakyness with our Cython tests if running_under_pytest(): now = False self.shellwidget.kernel_manager.shutdown_kernel(now=now) if self.shellwidget.kernel_client is not None: background(self.shellwidget.kernel_client.stop_channels) def interrupt_kernel(self): """Interrupt the associanted Spyder kernel if it's running""" # Needed to prevent a crash when a kernel is not running. # See issue 6299 try: self.shellwidget.request_interrupt_kernel() except RuntimeError: pass @Slot() def restart_kernel(self): """ Restart the associated kernel. Took this code from the qtconsole project Licensed under the BSD license """ sw = self.shellwidget if not running_under_pytest() and self.ask_before_restart: message = _('Are you sure you want to restart the kernel?') buttons = QMessageBox.Yes | QMessageBox.No result = QMessageBox.question(self, _('Restart kernel?'), message, buttons) else: result = None if (result == QMessageBox.Yes or running_under_pytest() or not self.ask_before_restart): if sw.kernel_manager: if self.infowidget.isVisible(): self.infowidget.hide() sw.show() try: sw.kernel_manager.restart_kernel(stderr=self.stderr_handle) except RuntimeError as e: sw._append_plain_text(_('Error restarting kernel: %s\n') % e, before_prompt=True) else: # For issue 6235. IPython was changing the setting of # %colors on windows by assuming it was using a dark # background. This corrects it based on the scheme. self.set_color_scheme(sw.syntax_style) sw._append_html(_("<br>Restarting kernel...\n<hr><br>"), before_prompt=False) else: sw._append_plain_text( _('Cannot restart a kernel not started by Spyder\n'), before_prompt=True) @Slot(str) def kernel_restarted_message(self, msg): """Show kernel restarted/died messages.""" if not self.is_error_shown: # If there are kernel creation errors, jupyter_client will # try to restart the kernel and qtconsole prints a # message about it. # So we read the kernel's stderr_file and display its # contents in the client instead of the usual message shown # by qtconsole. try: stderr = self._read_stderr() except Exception: stderr = None if stderr: self.show_kernel_error('<tt>%s</tt>' % stderr) else: self.shellwidget._append_html("<br>%s<hr><br>" % msg, before_prompt=False) @Slot() def inspect_object(self): """Show how to inspect an object with our Help plugin""" self.shellwidget._control.inspect_current_object() @Slot() def clear_line(self): """Clear a console line""" self.shellwidget._keyboard_quit() @Slot() def clear_console(self): """Clear the whole console""" self.shellwidget.clear_console() @Slot() def reset_namespace(self): """Resets the namespace by removing all names defined by the user""" self.shellwidget.reset_namespace(warning=self.reset_warning, message=True) def update_history(self): self.history = self.shellwidget._history @Slot(object) def show_syspath(self, syspath): """Show sys.path contents.""" if syspath is not None: editor = CollectionsEditor(self) editor.setup(syspath, title="sys.path contents", readonly=True, width=600, icon=ima.icon('syspath')) self.dialog_manager.show(editor) else: return @Slot(object) def show_env(self, env): """Show environment variables.""" self.dialog_manager.show(RemoteEnvDialog(env, parent=self)) def create_time_label(self): """Create elapsed time label widget (if necessary) and return it""" if self.time_label is None: self.time_label = QLabel() return self.time_label def show_time(self, end=False): """Text to show in time_label.""" if self.time_label is None: return elapsed_time = time.monotonic() - self.t0 # System time changed to past date, so reset start. if elapsed_time < 0: self.t0 = time.monotonic() elapsed_time = 0 if elapsed_time > 24 * 3600: # More than a day...! fmt = "%d %H:%M:%S" else: fmt = "%H:%M:%S" if end: color = "#AAAAAA" else: color = "#AA6655" text = "<span style=\'color: %s\'><b>%s" \ "</b></span>" % (color, time.strftime(fmt, time.gmtime(elapsed_time))) self.time_label.setText(text) def update_time_label_visibility(self): """Update elapsed time visibility.""" self.time_label.setVisible(self.show_elapsed_time) @Slot(bool) def set_elapsed_time_visible(self, state): """Slot to show/hide elapsed time label.""" self.show_elapsed_time = state if self.time_label is not None: self.time_label.setVisible(state) def set_info_page(self): """Set current info_page.""" if self.info_page is not None: self.infowidget.setHtml(self.info_page, QUrl.fromLocalFile(self.css_path)) #------ Private API ------------------------------------------------------- def _create_loading_page(self): """Create html page to show while the kernel is starting""" loading_template = Template(LOADING) loading_img = get_image_path('loading_sprites.png') if os.name == 'nt': loading_img = loading_img.replace('\\', '/') message = _("Connecting to kernel...") page = loading_template.substitute(css_path=self.css_path, loading_img=loading_img, message=message) return page def _create_blank_page(self): """Create html page to show while the kernel is starting""" loading_template = Template(BLANK) page = loading_template.substitute(css_path=self.css_path) return page def _show_loading_page(self): """Show animation while the kernel is loading.""" self.shellwidget.hide() self.infowidget.show() self.info_page = self.loading_page self.set_info_page() def _hide_loading_page(self): """Hide animation shown while the kernel is loading.""" self.infowidget.hide() self.shellwidget.show() self.info_page = self.blank_page self.set_info_page() self.shellwidget.sig_prompt_ready.disconnect(self._hide_loading_page) def _read_stderr(self): """Read the stderr file of the kernel.""" # We need to read stderr_file as bytes to be able to # detect its encoding with chardet f = open(self.stderr_file, 'rb') try: stderr_text = f.read() # This is needed to avoid showing an empty error message # when the kernel takes too much time to start. # See issue 8581 if not stderr_text: return '' # This is needed since the stderr file could be encoded # in something different to utf-8. # See issue 4191 encoding = get_coding(stderr_text) stderr_text = to_text_string(stderr_text, encoding) return stderr_text finally: f.close() def _show_mpl_backend_errors(self): """ Show possible errors when setting the selected Matplotlib backend. """ if not self.external_kernel: self.shellwidget.silent_execute( "get_ipython().kernel._show_mpl_backend_errors()") self.shellwidget.sig_prompt_ready.disconnect( self._show_mpl_backend_errors)
def __init__( self, settings: PartSettings, channel_control2: ChannelProperty, left_image: ResultImageView, synchronize: SynchronizeView, ): super().__init__() self._settings = settings self.left_panel = left_image self._ch_control2 = channel_control2 self.synchronize_val = False self.hide_left_panel_chk = QCheckBox("Hide left panel") self.hide_left_panel_chk.stateChanged.connect(self.hide_left_panel) self.synchronize_checkbox = QCheckBox("Synchronize view") self.synchronize_checkbox.stateChanged.connect( synchronize.set_synchronize) self.interactive_use = QCheckBox("Interactive use") self.execute_btn = QPushButton("Execute") self.execute_btn.clicked.connect(self.execute_algorithm) self.execute_btn.setStyleSheet("QPushButton{font-weight: bold;}") self.save_pipe_btn = QPushButton("Save pipeline") self.save_pipe_btn.clicked.connect(self.save_pipeline) self.save_pipe_btn.setToolTip( "Save current pipeline. Last element is last executed algorithm") self.choose_pipe = SearchComboBox() self.choose_pipe.addItem("<none>") # self.choose_pipe.addItems(list(self._settings.roi_pipelines.keys())) self.choose_pipe.textActivated.connect(self.choose_pipeline) self.choose_pipe.setToolTip("Execute chosen pipeline") self.save_profile_btn = QPushButton("Save profile") self.save_profile_btn.setToolTip("Save values from current view") self.save_profile_btn.clicked.connect(self.save_profile) self.choose_profile = SearchComboBox() self.choose_profile.addItem("<none>") # self.choose_profile.addItems(list(self._settings.roi_profiles.keys())) self.choose_profile.setToolTip( "Select profile to restore its settings. Execute if interactive is checked" ) # image state self.compare_btn = QPushButton("Compare") self.compare_btn.setDisabled(True) self.compare_btn.clicked.connect(self.compare_action) left_image.hide_signal.connect(self.compare_btn.setHidden) self.update_tooltips() self.choose_profile.textActivated.connect(self.change_profile) self.interactive_use.stateChanged.connect(self.execute_btn.setDisabled) self.interactive_use.stateChanged.connect(self.interactive_change) self.algorithm_choose_widget = AlgorithmChoose( settings, algorithm_description.analysis_algorithm_dict) self.algorithm_choose_widget.result.connect(self.execution_done) self.algorithm_choose_widget.finished.connect( self.calculation_finished) self.algorithm_choose_widget.value_changed.connect( self.interactive_algorithm_execute) self.algorithm_choose_widget.algorithm_changed.connect( self.interactive_algorithm_execute) self._settings.roi_profiles_changed.connect(self._update_profiles) self._settings.roi_pipelines_changed.connect(self._update_pipelines) self._update_pipelines() self._update_profiles() self.label = TextShow() layout = QVBoxLayout() layout2 = QHBoxLayout() layout2.setSpacing(1) layout2.setContentsMargins(0, 0, 0, 0) layout3 = QHBoxLayout() layout3.setContentsMargins(0, 0, 0, 0) layout.setContentsMargins(0, 0, 0, 0) layout5 = QHBoxLayout() layout5.setContentsMargins(0, 0, 0, 0) layout5.addWidget(self.save_pipe_btn) layout5.addWidget(self.choose_pipe) layout4 = QHBoxLayout() layout4.setContentsMargins(0, 0, 0, 0) layout4.addWidget(self.save_profile_btn) layout4.addWidget(self.choose_profile) layout3.addWidget(self.interactive_use) layout3.addWidget(self.execute_btn) layout.addLayout(layout5) layout.addLayout(layout4) layout.addLayout(layout3) layout.addWidget(self.algorithm_choose_widget, 1) # layout.addLayout(self.stack_layout) layout.addWidget(self.label) # layout.addStretch(1) layout2.addWidget(self.hide_left_panel_chk) layout2.addWidget(self.synchronize_checkbox) layout.addLayout(layout2) layout.addWidget(self._ch_control2) # layout.setSpacing(0) self.setLayout(layout)
def create_layout(self): cancel_box = QHBoxLayout() cancel_box.addWidget(self.close_button) grid1 = QGridLayout() grid2 = QGridLayout() #----------------------------------------- # setup self.radio_rectangular = QRadioButton('Rectangular') self.radio_cylindrical = QRadioButton('Cylindrical') self.radio_spherical = QRadioButton('Spherical') coord_type_layout = QHBoxLayout() coord_type_layout.addWidget(self.radio_rectangular) coord_type_layout.addWidget(self.radio_cylindrical) coord_type_layout.addWidget(self.radio_spherical) checkboxs = QButtonGroup(self) checkboxs.addButton(self.checkbox_region_all) checkboxs.addButton(self.checkbox_region_ids) vbox1 = QVBoxLayout() vbox1.addWidget(self.checkbox_region_all) vbox1.addWidget(self.checkbox_region_ids) #vbox1.addLayout(checkboxs) #----------------------------------------- irow = 0 grid2.addWidget(self.name, irow, 0) grid2.addWidget(self.name_edit, irow, 1) irow += 1 #grid2.addWidget(self.name, irow, 0) grid2.addWidget(self.description_edit, irow, 1) irow += 1 grid2.addWidget(self.location_x, irow, 0) grid2.addWidget(self.location_x_edit, irow, 1) irow += 1 grid2.addWidget(self.location_y, irow, 0) grid2.addWidget(self.location_y_edit, irow, 1) irow += 1 grid2.addWidget(self.location_z, irow, 0) grid2.addWidget(self.location_z_edit, irow, 1) irow += 1 #| Name EngineInlet | #| RegionMode * RegionID | #| * All | #| | #| AllowedRegions: | #| Region ID 3 | #| | #| PickMode * All | #| Pick Mode x On/Off | #| Pick Angle 20 deg | #| | #| Revert | #| RenumberRegions | #| Close | grid2.addWidget(self.region_id, irow, 0) grid2.addWidget(self.region_id_edit, irow, 1) irow += 1 #grid2.addWidget(self.pick_mode, irow, 0) grid2.addWidget(self.checkbox_pick_mode, irow, 0) irow += 1 grid2.addWidget(self.pick_angle, irow, 0) grid2.addWidget(self.pick_angle_edit, irow, 1) irow += 1 #grid2.addWidget(self.pi, irow, 0) #grid2.addLayout(coord_type_layout, irow, 1) #irow += 1 #grid2.addWidget(self.location, irow, 0) #grid2.addLayout(location_layout, irow, 1) #irow += 1 #------------------------------------ vbox = QVBoxLayout() vbox.addLayout(grid1) #vbox.addLayout(vbox1) #vbox.addStretch() vbox.addWidget(self.table) vbox.addLayout(grid2) vbox.addStretch() #vbox.addWidget(self.check_apply) vbox.addLayout(cancel_box) self.setLayout(vbox)
def __init__(self, parent, project_types): """Project creation dialog.""" super(ProjectDialog, self).__init__(parent=parent) self.plugin = parent self._project_types = project_types self.project_data = {} # Variables current_python_version = '.'.join([to_text_string(sys.version_info[0]), to_text_string(sys.version_info[1])]) python_versions = ['2.7', '3.4', '3.5'] if current_python_version not in python_versions: python_versions.append(current_python_version) python_versions = sorted(python_versions) self.project_name = None self.location = get_home_dir() # Widgets self.groupbox = QGroupBox() self.radio_new_dir = QRadioButton(_("New directory")) self.radio_from_dir = QRadioButton(_("Existing directory")) self.label_project_name = QLabel(_('Project name')) self.label_location = QLabel(_('Location')) self.label_project_type = QLabel(_('Project type')) self.label_python_version = QLabel(_('Python version')) self.text_project_name = QLineEdit() self.text_location = QLineEdit(get_home_dir()) self.combo_project_type = QComboBox() self.combo_python_version = QComboBox() self.label_information = QLabel("") self.button_select_location = QToolButton() self.button_cancel = QPushButton(_('Cancel')) self.button_create = QPushButton(_('Create')) self.bbox = QDialogButtonBox(Qt.Horizontal) self.bbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole) self.bbox.addButton(self.button_create, QDialogButtonBox.ActionRole) # Widget setup self.combo_python_version.addItems(python_versions) self.radio_new_dir.setChecked(True) self.text_location.setEnabled(True) self.text_location.setReadOnly(True) self.button_select_location.setIcon(get_std_icon('DirOpenIcon')) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) self.button_create.setEnabled(False) for (id_, name) in [(pt_id, pt.get_name()) for pt_id, pt in project_types.items()]: self.combo_project_type.addItem(name, id_) self.combo_python_version.setCurrentIndex( python_versions.index(current_python_version)) self.setWindowTitle(_('Create new project')) self.setFixedWidth(500) self.label_python_version.setVisible(False) self.combo_python_version.setVisible(False) # Layouts layout_top = QHBoxLayout() layout_top.addWidget(self.radio_new_dir) layout_top.addWidget(self.radio_from_dir) layout_top.addStretch(1) self.groupbox.setLayout(layout_top) layout_grid = QGridLayout() layout_grid.addWidget(self.label_project_name, 0, 0) layout_grid.addWidget(self.text_project_name, 0, 1, 1, 2) layout_grid.addWidget(self.label_location, 1, 0) layout_grid.addWidget(self.text_location, 1, 1) layout_grid.addWidget(self.button_select_location, 1, 2) layout_grid.addWidget(self.label_project_type, 2, 0) layout_grid.addWidget(self.combo_project_type, 2, 1, 1, 2) layout_grid.addWidget(self.label_python_version, 3, 0) layout_grid.addWidget(self.combo_python_version, 3, 1, 1, 2) layout_grid.addWidget(self.label_information, 4, 0, 1, 3) layout = QVBoxLayout() layout.addWidget(self.groupbox) layout.addSpacing(10) layout.addLayout(layout_grid) layout.addStretch() layout.addSpacing(20) layout.addWidget(self.bbox) self.setLayout(layout) # Signals and slots self.button_select_location.clicked.connect(self.select_location) self.button_create.clicked.connect(self.create_project) self.button_cancel.clicked.connect(self.close) self.radio_from_dir.clicked.connect(self.update_location) self.radio_new_dir.clicked.connect(self.update_location) self.text_project_name.textChanged.connect(self.update_location)
def __init__(self, viewer, metadata_levels, initial_classes, *args, **kwargs): super(Classifier,self).__init__(*args,**kwargs) self.viewer = viewer # open image if not already open if len(self.viewer.layers)<1: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("No image open, please select an image in the following dialog.") msg.exec() self.viewer.window.qt_viewer._open_files_dialog() if len(self.viewer.layers)<1: # still no image open raise ValueError("Could not find image layers.") # get image shape self.shape = self.viewer.layers[0].shape # check metadata levels if not metadata_levels: self.metadata_levels = [f'dim_{dim}' for dim in range(len(self.shape[:-2]))] elif len(metadata_levels)!=len(self.shape[:-2]): metadata_levels_warning = NapariNotification((f'Number of metadata_levels ({len(metadata_levels)}) does not match ' f'number of leading image dimensions ({len(self.shape[:-2])}); will use default metadata_levels.'), severity='warning') metadata_levels_warning.show() self.metadata_levels = [f'dim_{dim}' for dim in range(len(self.shape[:-2]))] else: self.metadata_levels = metadata_levels # load metadata self.load_metadata() # initialize widget layout = QHBoxLayout() ## io panel save_button = QPushButton('Save...',self) save_button.clicked.connect(self.save_results) io_panel = QWidget() io_layout = QVBoxLayout() io_layout.addWidget(save_button) io_panel.setLayout(io_layout) layout.addWidget(io_panel) ## class panel classes_panel = QGroupBox('classes') classes_panel.setMinimumWidth(CLASS_PANEL_MINIMUM_WIDTH) ### layout for adding classes add_classes_layout = QHBoxLayout() add_class_button = QPushButton('Add class',self) add_class_button.clicked.connect(self.click_add_class) self.new_class_text = QLineEdit(self) self.new_class_text.setAlignment(Qt.AlignLeft) add_classes_layout.addWidget(add_class_button) add_classes_layout.addWidget(self.new_class_text) ### layout for class buttons self.class_button_layout = QGridLayout() ### add sub layouts to class panel classes_layout = QVBoxLayout() classes_layout.addLayout(add_classes_layout) classes_layout.addLayout(self.class_button_layout) classes_panel.setLayout(classes_layout) layout.addWidget(classes_panel) ## set widget layout layout.setAlignment(Qt.AlignTop) layout.setSpacing(4) self.setLayout(layout) self.setMaximumHeight(GUI_MAXIMUM_HEIGHT) self.setMaximumWidth(GUI_MAXIMUM_WIDTH) # initialize classes self.classes = [] if initial_classes is not None: for initial_class in initial_classes: self.add_class(initial_class)
def _setup_views(self): """Creates the UI widgets.""" self.central_splitter = QSplitter(self, orientation=Qt.Vertical) layout = create_plugin_layout(self.tools_layout, self.central_splitter) self.setLayout(layout) # Tree widget self.obj_tree = ToggleColumnTreeView() self.obj_tree.setAlternatingRowColors(True) self.obj_tree.setModel(self._proxy_tree_model) self.obj_tree.setSelectionBehavior(QAbstractItemView.SelectRows) self.obj_tree.setUniformRowHeights(True) self.obj_tree.setAnimated(True) self.obj_tree.add_header_context_menu() # Stretch last column? # It doesn't play nice when columns are hidden and then shown again. obj_tree_header = self.obj_tree.header() obj_tree_header.setSectionsMovable(True) obj_tree_header.setStretchLastSection(False) add_actions(self.show_cols_submenu, self.obj_tree.toggle_column_actions_group.actions()) self.central_splitter.addWidget(self.obj_tree) # Bottom pane bottom_pane_widget = QWidget() bottom_layout = QHBoxLayout() bottom_layout.setSpacing(0) bottom_layout.setContentsMargins(5, 5, 5, 5) # left top right bottom bottom_pane_widget.setLayout(bottom_layout) self.central_splitter.addWidget(bottom_pane_widget) group_box = QGroupBox(_("Details")) bottom_layout.addWidget(group_box) v_group_layout = QVBoxLayout() h_group_layout = QHBoxLayout() h_group_layout.setContentsMargins(2, 2, 2, 2) # left top right bottom group_box.setLayout(v_group_layout) v_group_layout.addLayout(h_group_layout) # Radio buttons radio_widget = QWidget() radio_layout = QVBoxLayout() radio_layout.setContentsMargins(0, 0, 0, 0) # left top right bottom radio_widget.setLayout(radio_layout) self.button_group = QButtonGroup(self) for button_id, attr_detail in enumerate(self._attr_details): radio_button = QRadioButton(attr_detail.name) radio_layout.addWidget(radio_button) self.button_group.addButton(radio_button, button_id) self.button_group.buttonClicked[int].connect( self._change_details_field) self.button_group.button(0).setChecked(True) radio_layout.addStretch(1) h_group_layout.addWidget(radio_widget) # Editor widget self.editor = CodeEditor(self) self.editor.setReadOnly(True) h_group_layout.addWidget(self.editor) # Warining label about repr repr_label = QLabel( _("(*) Some objects have very large repr's, " "which can freeze Spyder. Please use this " "with care.")) v_group_layout.addWidget(repr_label) # Splitter parameters self.central_splitter.setCollapsible(0, False) self.central_splitter.setCollapsible(1, True) self.central_splitter.setSizes([500, 320]) self.central_splitter.setStretchFactor(0, 10) self.central_splitter.setStretchFactor(1, 0) # Connect signals # Keep a temporary reference of the selection_model to prevent # segfault in PySide. # See http://permalink.gmane.org/gmane.comp.lib.qt.pyside.devel/222 selection_model = self.obj_tree.selectionModel() selection_model.currentChanged.connect(self._update_details)
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) cancel_button = QPushButton() cancel_button.setIcon(ima.icon('DialogCloseButton')) cancel_button.hide() progress_layout.addWidget(self._progress_bar, alignment=Qt.AlignLeft) progress_layout.addWidget(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() ok_button = QPushButton(_('OK')) button_layout.addStretch() button_layout.addWidget(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 ok_button.clicked.connect(self.sig_ok_button_clicked) cancel_button.clicked.connect(self.sig_cancel_button_clicked) self._progress_filter.sig_hover_enter.connect( lambda: cancel_button.show()) self._progress_filter.sig_hover_leave.connect( lambda: cancel_button.hide())
def __init__(self, parent, search_text, search_text_regexp, search_path, exclude, exclude_idx, exclude_regexp, supported_encodings, in_python_path, more_options, case_sensitive, external_path_history): QWidget.__init__(self, parent) if search_path is None: search_path = getcwd_or_home() self.path = '' self.project_path = None self.file_path = None self.external_path = None self.external_path_history = external_path_history 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] if not isinstance(external_path_history, (list, tuple)): external_path_history = [external_path_history] 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.case_button = create_toolbutton(self, icon=get_icon("upper_lower.png"), tip=_("Case Sensitive")) self.case_button.setCheckable(True) self.case_button.setChecked(case_sensitive) 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.case_button, 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() search_on_label = QLabel(_("Search in:")) self.path_selection_combo = PatternComboBox(self, exclude, _('Search directory')) self.path_selection_combo.setEditable(False) self.path_selection_contents = QListWidget(self.path_selection_combo) self.path_selection_contents.hide() self.path_selection_combo.setModel( self.path_selection_contents.model()) self.path_selection_contents.addItem(_("Current working directory")) item = self.path_selection_contents.item(0) item.setToolTip( _("Search in all files and " "directories present on the" "current Spyder path")) self.path_selection_contents.addItem(_("Project")) item = self.path_selection_contents.item(1) item.setToolTip( _("Search in all files and " "directories present on the" "current project path " "(If opened)")) item.setFlags(item.flags() & ~Qt.ItemIsEnabled) self.path_selection_contents.addItem(_("File").replace('&', '')) item = self.path_selection_contents.item(2) item.setToolTip(_("Search in current opened file")) self.path_selection_contents.addItem(_("Select other directory")) item = self.path_selection_contents.item(3) item.setToolTip(_("Search in other folder present on the file system")) self.path_selection_combo.insertSeparator(3) self.path_selection_combo.insertSeparator(5) for path in external_path_history: item = ExternalPathItem(None, path) self.path_selection_contents.addItem(item) self.path_selection_combo.currentIndexChanged.connect( self.path_selection_changed) hlayout3.addWidget(search_on_label) hlayout3.addWidget(self.path_selection_combo) 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)
def __init__(self, parent, opacity, duration, easing_curve, tour=None, color_top=None, color_back=None, combobox_background=None): super(FadingTipBox, self).__init__(parent, opacity, duration, easing_curve) self.holder = self.anim # needed for qt to work self.parent = parent self.tour = tour self.frames = None self.offset_shadow = 0 self.fixed_width = 300 self.key_pressed = None self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.Dialog | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setModal(False) # Widgets def toolbutton(icon): bt = QToolButton() bt.setAutoRaise(True) bt.setIcon(icon) return bt self.button_close = toolbutton(ima.icon("tour.close")) self.button_home = toolbutton(ima.icon("tour.home")) self.button_previous = toolbutton(ima.icon("tour.previous")) self.button_end = toolbutton(ima.icon("tour.end")) self.button_next = toolbutton(ima.icon("tour.next")) self.button_run = QPushButton(_('Run code')) self.button_disable = None self.button_current = QToolButton() self.label_image = QLabel() self.label_title = QLabel() self.combo_title = QComboBox() self.label_current = QLabel() self.label_content = QLabel() self.label_content.setMinimumWidth(self.fixed_width) self.label_content.setMaximumWidth(self.fixed_width) self.label_current.setAlignment(Qt.AlignCenter) self.label_content.setWordWrap(True) self.widgets = [ self.label_content, self.label_title, self.label_current, self.combo_title, self.button_close, self.button_run, self.button_next, self.button_previous, self.button_end, self.button_home, self.button_current ] arrow = get_image_path('hide.png') self.color_top = color_top self.color_back = color_back self.combobox_background = combobox_background self.stylesheet = '''QComboBox {{ padding-left: 5px; background-color: {} border-width: 0px; border-radius: 0px; min-height:20px; max-height:20px; }} QComboBox::drop-down {{ subcontrol-origin: padding; subcontrol-position: top left; border-width: 0px; }} QComboBox::down-arrow {{ image: url({}); }} '''.format(self.combobox_background.name(), arrow) # Windows fix, slashes should be always in unix-style self.stylesheet = self.stylesheet.replace('\\', '/') self.setFocusPolicy(Qt.StrongFocus) for widget in self.widgets: widget.setFocusPolicy(Qt.NoFocus) widget.setStyleSheet(self.stylesheet) layout_top = QHBoxLayout() layout_top.addWidget(self.combo_title) layout_top.addStretch() layout_top.addWidget(self.button_close) layout_top.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_content = QHBoxLayout() layout_content.addWidget(self.label_content) layout_content.addWidget(self.label_image) layout_content.addSpacerItem(QSpacerItem(5, 5)) layout_run = QHBoxLayout() layout_run.addStretch() layout_run.addWidget(self.button_run) layout_run.addStretch() layout_run.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout_navigation = QHBoxLayout() layout_navigation.addWidget(self.button_home) layout_navigation.addWidget(self.button_previous) layout_navigation.addStretch() layout_navigation.addWidget(self.label_current) layout_navigation.addStretch() layout_navigation.addWidget(self.button_next) layout_navigation.addWidget(self.button_end) layout_navigation.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout = QVBoxLayout() layout.addLayout(layout_top) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_content) layout.addLayout(layout_run) layout.addStretch() layout.addSpacerItem(QSpacerItem(15, 15)) layout.addLayout(layout_navigation) layout.addSpacerItem( QSpacerItem(self.offset_shadow, self.offset_shadow)) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.set_funcs_before_fade_in([self._disable_widgets]) self.set_funcs_after_fade_in([self._enable_widgets, self.setFocus]) self.set_funcs_before_fade_out([self._disable_widgets]) self.setContextMenuPolicy(Qt.CustomContextMenu)
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) add_newline_box = newcb(_( "Insert a newline at the end if one does not exist when saving " "a file"), 'add_newline', default=False) remove_trail_newline_box = newcb( _("Trim all newlines after the final one when saving a file"), 'always_remove_trailing_newlines', 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(add_newline_box) sourcecode_layout.addWidget(remove_trail_newline_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)
def __init__(self, parent, max_entries=100): QWidget.__init__(self, parent) self.setWindowTitle("Profiler") self.output = None self.error_output = None 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) 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 setup(self): """Setup the ShortcutEditor with the provided arguments.""" # Widgets icon_info = HelperToolButton() icon_info.setIcon(get_std_icon('MessageBoxInformation')) layout_icon_info = QVBoxLayout() layout_icon_info.setContentsMargins(0, 0, 0, 0) layout_icon_info.setSpacing(0) layout_icon_info.addWidget(icon_info) layout_icon_info.addStretch(100) self.label_info = QLabel() self.label_info.setText( _("Press the new shortcut and select 'Ok' to confirm, " "click 'Cancel' to revert to the previous state, " "or use 'Clear' to unbind the command from a shortcut.")) self.label_info.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.label_info.setWordWrap(True) layout_info = QHBoxLayout() layout_info.setContentsMargins(0, 0, 0, 0) layout_info.addLayout(layout_icon_info) layout_info.addWidget(self.label_info) layout_info.setStretch(1, 100) self.label_current_sequence = QLabel(_("Current shortcut:")) self.text_current_sequence = QLabel(self.current_sequence) self.label_new_sequence = QLabel(_("New shortcut:")) self.text_new_sequence = ShortcutLineEdit(self) self.text_new_sequence.setPlaceholderText(_("Press shortcut.")) self.helper_button = HelperToolButton() self.helper_button.setIcon(QIcon()) self.label_warning = QLabel() self.label_warning.setWordWrap(True) self.label_warning.setAlignment(Qt.AlignTop | Qt.AlignLeft) self.button_default = QPushButton(_('Default')) self.button_ok = QPushButton(_('Ok')) self.button_ok.setEnabled(False) self.button_clear = QPushButton(_('Clear')) self.button_cancel = QPushButton(_('Cancel')) button_box = QHBoxLayout() button_box.addWidget(self.button_default) button_box.addStretch(100) button_box.addWidget(self.button_ok) button_box.addWidget(self.button_clear) button_box.addWidget(self.button_cancel) # New Sequence button box self.btn_clear_sequence = create_toolbutton( self, icon=ima.icon('editclear'), tip=_("Clear all entered key sequences"), triggered=self.clear_new_sequence) self.button_back_sequence = create_toolbutton( self, icon=ima.icon('ArrowBack'), tip=_("Remove last key sequence entered"), triggered=self.back_new_sequence) newseq_btnbar = QHBoxLayout() newseq_btnbar.setSpacing(0) newseq_btnbar.setContentsMargins(0, 0, 0, 0) newseq_btnbar.addWidget(self.button_back_sequence) newseq_btnbar.addWidget(self.btn_clear_sequence) # Setup widgets self.setWindowTitle(_('Shortcut: {0}').format(self.name)) self.helper_button.setToolTip('') style = """ QToolButton { margin:1px; border: 0px solid grey; padding:0px; border-radius: 0px; }""" self.helper_button.setStyleSheet(style) icon_info.setToolTip('') icon_info.setStyleSheet(style) # Layout layout_sequence = QGridLayout() layout_sequence.setContentsMargins(0, 0, 0, 0) layout_sequence.addLayout(layout_info, 0, 0, 1, 4) layout_sequence.addItem(QSpacerItem(15, 15), 1, 0, 1, 4) layout_sequence.addWidget(self.label_current_sequence, 2, 0) layout_sequence.addWidget(self.text_current_sequence, 2, 2) layout_sequence.addWidget(self.label_new_sequence, 3, 0) layout_sequence.addWidget(self.helper_button, 3, 1) layout_sequence.addWidget(self.text_new_sequence, 3, 2) layout_sequence.addLayout(newseq_btnbar, 3, 3) layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2) layout_sequence.setColumnStretch(2, 100) layout_sequence.setRowStretch(4, 100) layout = QVBoxLayout(self) layout.addLayout(layout_sequence) layout.addSpacing(10) layout.addLayout(button_box) layout.setSizeConstraint(layout.SetFixedSize) # Signals self.button_ok.clicked.connect(self.accept_override) self.button_clear.clicked.connect(self.unbind_shortcut) self.button_cancel.clicked.connect(self.reject) self.button_default.clicked.connect(self.set_sequence_to_default) # Set all widget to no focus so that we can register <Tab> key # press event. widgets = (self.label_warning, self.helper_button, self.text_new_sequence, self.button_clear, self.button_default, self.button_cancel, self.button_ok, self.btn_clear_sequence, self.button_back_sequence) for w in widgets: w.setFocusPolicy(Qt.NoFocus) w.clearFocus()
class QtAboutKeyBindings(QDialog): """Qt dialog window for displaying keybinding information. Parameters ---------- viewer : napari.components.ViewerModel Napari viewer containing the rendered scene, layers, and controls. key_map_handler : napari.utils.key_bindings.KeyMapHandler Handler for key mapping and calling functionality. Attributes ---------- key_bindings_strs : collections.OrderedDict Ordered dictionary of hotkey shortcuts and associated key bindings. Dictionary keys include: - 'All active key bindings' - 'Image layer' - 'Labels layer' - 'Points layer' - 'Shapes layer' - 'Surface layer' - 'Vectors layer' layout : qtpy.QtWidgets.QVBoxLayout Layout of the widget. layerTypeComboBox : qtpy.QtWidgets.QComboBox Dropdown menu to select layer type. textEditBox : qtpy.QtWidgets.QTextEdit Text box widget containing table of key bindings information. viewer : napari.components.ViewerModel Napari viewer containing the rendered scene, layers, and controls. """ ALL_ACTIVE_KEYBINDINGS = 'All active key bindings' def __init__(self, viewer, key_map_handler, parent=None): super().__init__(parent=parent) self.viewer = viewer self.layout = QVBoxLayout() self.setWindowTitle('Keybindings') self.setWindowModality(Qt.NonModal) self.setLayout(self.layout) # stacked key bindings widgets self.textEditBox = QTextEdit() self.textEditBox.setTextInteractionFlags(Qt.TextSelectableByMouse) self.textEditBox.setMinimumWidth(360) # Can switch to a normal dict when our minimum Python is 3.7 self.key_bindings_strs = OrderedDict() self.key_bindings_strs[self.ALL_ACTIVE_KEYBINDINGS] = '' self.key_map_handler = key_map_handler theme = get_theme(self.viewer.theme) col = theme['secondary'] layers = [ napari.layers.Image, napari.layers.Labels, napari.layers.Points, napari.layers.Shapes, napari.layers.Surface, napari.layers.Vectors, ] for layer in layers: if len(layer.class_keymap) == 0: text = 'No key bindings' else: text = get_key_bindings_summary(layer.class_keymap, col=col) self.key_bindings_strs[f"{layer.__name__} layer"] = text # layer type selection self.layerTypeComboBox = QComboBox() self.layerTypeComboBox.addItems(list(self.key_bindings_strs)) self.layerTypeComboBox.activated[str].connect(self.change_layer_type) self.layerTypeComboBox.setCurrentText(self.ALL_ACTIVE_KEYBINDINGS) # self.change_layer_type(current_layer) layer_type_layout = QHBoxLayout() layer_type_layout.setContentsMargins(10, 5, 0, 0) layer_type_layout.addWidget(self.layerTypeComboBox) layer_type_layout.addStretch(1) layer_type_layout.setSpacing(0) self.layout.addLayout(layer_type_layout) self.layout.addWidget(self.textEditBox, 1) self.viewer.events.theme.connect(self.update_active_layer) self.update_active_layer() def change_layer_type(self, text): """Change layer type selected in dropdown menu. Parameters ---------- text : str Dictionary key to access key bindings associated with the layer. Available keys include: - 'All active key bindings' - 'Image layer' - 'Labels layer' - 'Points layer' - 'Shapes layer' - 'Surface layer' - 'Vectors layer' """ self.textEditBox.setHtml(self.key_bindings_strs[text]) def update_active_layer(self, event=None): """Update the active layer and display key bindings for that layer type. Parameters ---------- event : napari.utils.event.Event, optional The napari event that triggered this method, by default None. """ theme = get_theme(self.viewer.theme) col = theme['secondary'] # Add class and instance viewer key bindings text = get_key_bindings_summary(self.key_map_handler.active_keymap, col=col) # Update layer speficic key bindings if all active are displayed self.key_bindings_strs[self.ALL_ACTIVE_KEYBINDINGS] = text if self.layerTypeComboBox.currentText() == self.ALL_ACTIVE_KEYBINDINGS: self.textEditBox.setHtml(text)
def setup_page(self): names = self.get_option("names") try: names.pop(names.index(u'Custom')) except ValueError: pass custom_names = self.get_option("custom_names", []) # Interface options theme_group = QGroupBox(_("Main interface")) # Interface Widgets ui_themes = ['Automatic', 'Light', 'Dark'] ui_theme_choices = list( zip(ui_themes, [ui_theme.lower() for ui_theme in ui_themes])) ui_theme_combo = self.create_combobox(_('Interface theme'), ui_theme_choices, 'ui_theme', restart=True) styles = [str(txt) for txt in list(QStyleFactory.keys())] # Don't offer users the possibility to change to a different # style in Gtk-based desktops # See spyder-ide/spyder#2036. if is_gtk_desktop() and ('GTK+' in styles): styles = ['GTK+'] choices = list(zip(styles, [style.lower() for style in styles])) style_combo = self.create_combobox(_('Qt windows style'), choices, 'windows_style', default=self.main.default_style) self.style_combobox = style_combo.combobox themes = ['Spyder 2', 'Spyder 3'] icon_choices = list(zip(themes, [theme.lower() for theme in themes])) icons_combo = self.create_combobox(_('Icon theme'), icon_choices, 'icon_theme', restart=True) theme_comboboxes_layout = QGridLayout() theme_comboboxes_layout.addWidget(ui_theme_combo.label, 0, 0) theme_comboboxes_layout.addWidget(ui_theme_combo.combobox, 0, 1) theme_comboboxes_layout.addWidget(style_combo.label, 1, 0) theme_comboboxes_layout.addWidget(self.style_combobox, 1, 1) theme_comboboxes_layout.addWidget(icons_combo.label, 2, 0) theme_comboboxes_layout.addWidget(icons_combo.combobox, 2, 1) theme_layout = QVBoxLayout() theme_layout.addLayout(theme_comboboxes_layout) theme_group.setLayout(theme_layout) # Syntax coloring options syntax_group = QGroupBox(_("Syntax highlighting theme")) # Syntax Widgets edit_button = QPushButton(_("Edit selected scheme")) create_button = QPushButton(_("Create new scheme")) self.delete_button = QPushButton(_("Delete scheme")) self.reset_button = QPushButton(_("Reset to defaults")) self.preview_editor = SimpleCodeEditor(self) self.stacked_widget = QStackedWidget(self) self.scheme_editor_dialog = SchemeEditor(parent=self, stack=self.stacked_widget) self.scheme_choices_dict = {} schemes_combobox_widget = self.create_combobox('', [('', '')], 'selected') self.schemes_combobox = schemes_combobox_widget.combobox # Syntax layout syntax_layout = QGridLayout(syntax_group) btns = [ self.schemes_combobox, edit_button, self.reset_button, create_button, self.delete_button ] for i, btn in enumerate(btns): syntax_layout.addWidget(btn, i, 1) syntax_layout.setColumnStretch(0, 1) syntax_layout.setColumnStretch(1, 2) syntax_layout.setColumnStretch(2, 1) syntax_layout.setContentsMargins(0, 12, 0, 12) # Fonts options fonts_group = QGroupBox(_("Fonts")) # Fonts widgets self.plain_text_font = self.create_fontgroup( option='font', title=_("Plain text"), fontfilters=QFontComboBox.MonospacedFonts, without_group=True) self.rich_text_font = self.create_fontgroup(option='rich_font', title=_("Rich text"), without_group=True) # Fonts layouts fonts_layout = QGridLayout(fonts_group) fonts_layout.addWidget(self.plain_text_font.fontlabel, 0, 0) fonts_layout.addWidget(self.plain_text_font.fontbox, 0, 1) fonts_layout.addWidget(self.plain_text_font.sizelabel, 0, 2) fonts_layout.addWidget(self.plain_text_font.sizebox, 0, 3) fonts_layout.addWidget(self.rich_text_font.fontlabel, 1, 0) fonts_layout.addWidget(self.rich_text_font.fontbox, 1, 1) fonts_layout.addWidget(self.rich_text_font.sizelabel, 1, 2) fonts_layout.addWidget(self.rich_text_font.sizebox, 1, 3) fonts_layout.setRowStretch(fonts_layout.rowCount(), 1) # Left options layout options_layout = QVBoxLayout() options_layout.addWidget(theme_group) options_layout.addWidget(syntax_group) options_layout.addWidget(fonts_group) # Right preview layout preview_group = QGroupBox(_("Preview")) preview_layout = QVBoxLayout() preview_layout.addWidget(self.preview_editor) preview_group.setLayout(preview_layout) # Combined layout combined_layout = QGridLayout() combined_layout.setRowStretch(0, 1) combined_layout.setColumnStretch(1, 100) combined_layout.addLayout(options_layout, 0, 0) combined_layout.addWidget(preview_group, 0, 1) self.setLayout(combined_layout) # Signals and slots create_button.clicked.connect(self.create_new_scheme) edit_button.clicked.connect(self.edit_scheme) self.reset_button.clicked.connect(self.reset_to_default) self.delete_button.clicked.connect(self.delete_scheme) self.schemes_combobox.currentIndexChanged.connect(self.update_preview) self.schemes_combobox.currentIndexChanged.connect(self.update_buttons) # Setup for name in names: self.scheme_editor_dialog.add_color_scheme_stack(name) for name in custom_names: self.scheme_editor_dialog.add_color_scheme_stack(name, custom=True) self.update_combobox() self.update_preview() self.update_qt_style_combobox()
def setup_page(self): about_label = QLabel( _("The following are the default options for " "running files.These options may be overriden " "using the <b>Configuration per file</b> entry " "of the <b>Run</b> menu.")) about_label.setWordWrap(True) interpreter_group = QGroupBox(_("Console")) interpreter_bg = QButtonGroup(interpreter_group) self.current_radio = self.create_radiobutton( CURRENT_INTERPRETER, CURRENT_INTERPRETER_OPTION, True, button_group=interpreter_bg) self.dedicated_radio = self.create_radiobutton( DEDICATED_INTERPRETER, DEDICATED_INTERPRETER_OPTION, False, button_group=interpreter_bg) self.systerm_radio = self.create_radiobutton( SYSTERM_INTERPRETER, SYSTERM_INTERPRETER_OPTION, False, button_group=interpreter_bg) interpreter_layout = QVBoxLayout() interpreter_group.setLayout(interpreter_layout) interpreter_layout.addWidget(self.current_radio) interpreter_layout.addWidget(self.dedicated_radio) interpreter_layout.addWidget(self.systerm_radio) general_group = QGroupBox(_("General settings")) post_mortem = self.create_checkbox(POST_MORTEM, 'post_mortem', False) clear_variables = self.create_checkbox(CLEAR_ALL_VARIABLES, 'clear_namespace', False) console_namespace = self.create_checkbox(CONSOLE_NAMESPACE, 'console_namespace', False) general_layout = QVBoxLayout() general_layout.addWidget(clear_variables) general_layout.addWidget(console_namespace) general_layout.addWidget(post_mortem) general_group.setLayout(general_layout) wdir_group = QGroupBox(_("Working directory settings")) wdir_bg = QButtonGroup(wdir_group) wdir_label = QLabel(_("Default working directory is:")) wdir_label.setWordWrap(True) dirname_radio = self.create_radiobutton(FILE_DIR, WDIR_USE_SCRIPT_DIR_OPTION, True, button_group=wdir_bg) cwd_radio = self.create_radiobutton(CW_DIR, WDIR_USE_CWD_DIR_OPTION, False, button_group=wdir_bg) thisdir_radio = self.create_radiobutton(FIXED_DIR, WDIR_USE_FIXED_DIR_OPTION, False, button_group=wdir_bg) thisdir_bd = self.create_browsedir("", WDIR_FIXED_DIR_OPTION, getcwd_or_home()) thisdir_radio.toggled.connect(thisdir_bd.setEnabled) dirname_radio.toggled.connect(thisdir_bd.setDisabled) cwd_radio.toggled.connect(thisdir_bd.setDisabled) thisdir_layout = QHBoxLayout() thisdir_layout.addWidget(thisdir_radio) thisdir_layout.addWidget(thisdir_bd) wdir_layout = QVBoxLayout() wdir_layout.addWidget(wdir_label) wdir_layout.addWidget(dirname_radio) wdir_layout.addWidget(cwd_radio) wdir_layout.addLayout(thisdir_layout) wdir_group.setLayout(wdir_layout) external_group = QGroupBox(_("External system terminal")) interact_after = self.create_checkbox(INTERACT, 'interact', False) external_layout = QVBoxLayout() external_layout.addWidget(interact_after) external_group.setLayout(external_layout) firstrun_cb = self.create_checkbox( ALWAYS_OPEN_FIRST_RUN % _("Run Settings dialog"), ALWAYS_OPEN_FIRST_RUN_OPTION, False) vlayout = QVBoxLayout(self) vlayout.addWidget(about_label) vlayout.addSpacing(10) vlayout.addWidget(interpreter_group) vlayout.addWidget(general_group) vlayout.addWidget(wdir_group) vlayout.addWidget(external_group) vlayout.addWidget(firstrun_cb) vlayout.addStretch(1)
class PluginMainWidget(QWidget, SpyderWidgetMixin, SpyderToolbarMixin): """ Spyder plugin main widget class. This class handles both a dockwidget pane and a floating window widget (undocked pane). Notes ----- All Spyder dockable plugins define a main widget that must subclass this. This widget is a subclass of QMainWindow that consists of a single, central widget and a set of toolbars that are stacked above or below that widget. The toolbars are not moveable nor floatable and must occupy the entire horizontal space available for the plugin. This mean that toolbars must be stacked vertically and cannot be placed horizontally next to each other. """ # --- Attributes # ------------------------------------------------------------------------ ENABLE_SPINNER = False """ This attribute enables/disables showing a spinner on the top right to the left of the corner menu widget (Hamburguer menu). Plugins that provide actions that take time should make this `True` and use accordingly with the `start_spinner`/`stop_spinner` methods. The Find in files plugin is an example of a core plugin that uses it. Parameters ---------- ENABLE_SPINNER: bool If `True` an extra space will be added to the toolbar (even if the spinner is not moving) to avoid items jumping to the left/right when the spinner appears. If `False` no extra space will be added. Default is False. """ CONTEXT_NAME = None """ This optional attribute defines the context name under which actions, toolbars, toolbuttons and menus should be registered on the Spyder global registry. If actions, toolbars, toolbuttons or menus belong to the global scope of the plugin, then this attribute should have a `None` value. """ # --- Signals # ------------------------------------------------------------------------ sig_free_memory_requested = Signal() """ This signal can be emitted to request the main application to garbage collect deleted objects. """ sig_quit_requested = Signal() """ This signal can be emitted to request the main application to quit. """ sig_restart_requested = Signal() """ This signal can be emitted to request the main application to restart. """ sig_redirect_stdio_requested = Signal(bool) """ This signal can be emitted to request the main application to redirect standard output/error when using Open/Save/Browse dialogs within widgets. Parameters ---------- enable: bool Enable/Disable standard input/output redirection. """ sig_exception_occurred = Signal(dict) """ This signal can be emitted to report an exception handled by this widget. Parameters ---------- error_data: dict The dictionary containing error data. The expected keys are: >>> error_data= { "text": str, "is_traceback": bool, "repo": str, "title": str, "label": str, "steps": str, } Notes ----- The `is_traceback` key indicates if `text` contains plain text or a Python error traceback. The `title` and `repo` keys indicate how the error data should customize the report dialog and Github error submission. The `label` and `steps` keys allow customizing the content of the error dialog. """ sig_toggle_view_changed = Signal(bool) """ This action is emitted to inform the visibility of a dockable plugin has changed. This is triggered by checking/unchecking the entry for a pane in the `View > Panes` menu. Parameters ---------- visible: bool New visibility of the dockwidget. """ sig_update_ancestor_requested = Signal() """ This signal is emitted to inform the main window that a child widget needs its ancestor to be updated. """ def __init__(self, name, plugin, parent=None): super().__init__(parent=parent, class_parent=plugin) # Attributes # -------------------------------------------------------------------- self._is_tab = False self._name = name self._plugin = plugin self._parent = parent self._default_margins = None self.is_maximized = None self.is_visible = None self.dock_action = None self.undock_action = None self.close_action = None self._toolbars_already_rendered = False # Attribute used to access the action, toolbar, toolbutton and menu # registries self.PLUGIN_NAME = name # We create our toggle action instead of using the one that comes with # dockwidget because it was not possible to raise and focus the plugin self.toggle_view_action = None self._toolbars = OrderedDict() self._auxiliary_toolbars = OrderedDict() # Widgets # -------------------------------------------------------------------- self.windowwidget = None self.dockwidget = None self._icon = QIcon() self._spinner = None if self.ENABLE_SPINNER: self._spinner = create_waitspinner(size=16, parent=self) self._corner_widget = MainCornerWidget( parent=self, name=PluginMainWidgetWidgets.CornerWidget, ) self._main_toolbar = MainWidgetToolbar( parent=self, title=_("Main widget toolbar"), ) self._main_toolbar.ID = 'main_toolbar' TOOLBAR_REGISTRY.register_reference(self._main_toolbar, self._main_toolbar.ID, self.PLUGIN_NAME, self.CONTEXT_NAME) self._corner_toolbar = MainWidgetToolbar( parent=self, title=_("Main widget corner toolbar"), ) self._corner_toolbar.ID = 'corner_toolbar', TOOLBAR_REGISTRY.register_reference(self._corner_toolbar, self._corner_toolbar.ID, self.PLUGIN_NAME, self.CONTEXT_NAME) self._corner_toolbar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding) self._options_menu = self.create_menu( PluginMainWidgetMenus.Options, title=_('Options menu'), ) # Layout # -------------------------------------------------------------------- self._main_layout = QVBoxLayout() self._toolbars_layout = QVBoxLayout() self._main_toolbar_layout = QHBoxLayout() self._toolbars_layout.setContentsMargins(0, 0, 0, 0) self._toolbars_layout.setSpacing(0) self._main_toolbar_layout.setContentsMargins(0, 0, 0, 0) self._main_toolbar_layout.setSpacing(0) self._main_layout.setContentsMargins(0, 0, 0, 0) self._main_layout.setSpacing(0) # Add inititals layouts self._main_toolbar_layout.addWidget(self._main_toolbar, stretch=10000) self._main_toolbar_layout.addWidget(self._corner_toolbar, stretch=1) self._toolbars_layout.addLayout(self._main_toolbar_layout) self._main_layout.addLayout(self._toolbars_layout, stretch=1) # --- Private Methods # ------------------------------------------------------------------------ def _setup(self): """ Setup default actions, create options menu, and connect signals. """ # Tabs children = self.findChildren(Tabs) if children: for child in children: self._is_tab = True # For widgets that use tabs, we add the corner widget using # the setCornerWidget method. child.setCornerWidget(self._corner_widget) # This is needed to ensure the corner ToolButton (hamburguer # menu) is aligned with plugins that use Toolbars vs # CornerWidgets # See: spyder-ide/spyder#13600 # left, top, right, bottom if os.name == "nt": self._corner_widget.setContentsMargins(0, 0, 2, 0) else: self._corner_widget.setContentsMargins(0, 2, 2, 0) break self._options_button = self.create_toolbutton( PluginMainWidgetWidgets.OptionsToolButton, text=_('Options'), icon=self.create_icon('tooloptions'), ) self.add_corner_widget( PluginMainWidgetWidgets.OptionsToolButton, self._options_button, ) if self.ENABLE_SPINNER: self.add_corner_widget( PluginMainWidgetWidgets.Spinner, self._spinner, ) # Widget setup # -------------------------------------------------------------------- self._main_toolbar.setVisible(not self._is_tab) self._corner_toolbar.setVisible(not self._is_tab) self._options_button.setPopupMode(QToolButton.InstantPopup) # Create default widget actions self.dock_action = self.create_action( name=PluginMainWidgetActions.DockPane, text=_("Dock"), tip=_("Dock the pane"), icon=self.create_icon('dock'), triggered=self.close_window, ) self.undock_action = self.create_action( name=PluginMainWidgetActions.UndockPane, text=_("Undock"), tip=_("Undock the pane"), icon=self.create_icon('undock'), triggered=self.create_window, ) self.close_action = self.create_action( name=PluginMainWidgetActions.ClosePane, text=_("Close"), tip=_("Close the pane"), icon=self.create_icon('close_pane'), triggered=self.close_dock, ) # We use this instead of the QDockWidget.toggleViewAction self.toggle_view_action = self.create_action( name='switch to ' + self._name, text=self.get_title(), toggled=lambda checked: self.toggle_view(checked), context=Qt.WidgetWithChildrenShortcut, shortcut_context='_', ) bottom_section = OptionsMenuSections.Bottom for item in [self.undock_action, self.close_action, self.dock_action]: self.add_item_to_menu( item, self._options_menu, section=bottom_section, ) self._options_button.setMenu(self._options_menu) self._options_menu.aboutToShow.connect(self._update_actions) # Hide icons in Mac plugin menus if sys.platform == 'darwin': self._options_menu.aboutToHide.connect( lambda menu=self._options_menu: set_menu_icons(menu, False)) # For widgets that do not use tabs, we add the corner widget to the # corner toolbar if not self._is_tab: self.add_item_to_toolbar( self._corner_widget, toolbar=self._corner_toolbar, section="corner", ) # Update title self.setWindowTitle(self.get_title()) self._update_style() def _update_style(self): """ Update style of the widget. """ qss = r""" QToolButton::menu-indicator { image: none; } QToolButton { margin: 0px; } """ self._options_button.setStyleSheet(textwrap.dedent(qss)) def _update_actions(self): """ Refresh Options menu. """ show_dock_actions = self.windowwidget is None self.undock_action.setVisible(show_dock_actions) self.close_action.setVisible(show_dock_actions) self.dock_action.setVisible(not show_dock_actions) if sys.platform == 'darwin': try: set_menu_icons(self.get_menu(PluginMainWidgetMenus.Options), True) except KeyError: # Prevent unexpected errors on the test suite. pass # Widget setup # -------------------------------------------------------------------- self.update_actions() self._update_style() @Slot(bool) def _on_top_level_change(self, top_level): """ Actions to perform when a plugin is undocked to be moved. """ self.undock_action.setDisabled(top_level) # --- Public Qt overriden methods # ------------------------------------------------------------------------ def setLayout(self, layout): """ Set layout of the main widget of this plugin. """ self._main_layout.addLayout(layout, stretch=1000000) super().setLayout(self._main_layout) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) # --- Public methods to use # ------------------------------------------------------------------------ def get_plugin(self): """ Return the parent plugin. """ return self._plugin def get_action(self, name, context: Optional[str] = None, plugin: Optional[str] = None): """ Return action by name. """ plugin = self.PLUGIN_NAME if plugin is None else plugin context = self.CONTEXT_NAME if context is None else context return ACTION_REGISTRY.get_reference(name, plugin, context) def add_corner_widget(self, widget_id, widget, before=None): """ Add widget to corner, that is to the left of the last added widget. Parameters ---------- widget_id: str Unique name of the widget. widget: QWidget Any QWidget to add in the corner widget. before: QWidget Insert the widget before this widget. Notes ----- By default widgets are added to the left of the last corner widget. The central widget provides an options menu button and a spinner so any additional widgets will be placed to the left of the spinner, if visible. """ self._corner_widget.add_widget(widget_id, widget) def get_corner_widget(self, name): """ Return the a widget inside the corner widget by name. Parameters ---------- name: str Unique name of the widget. """ return self._corner_widget.get_widget(name) def start_spinner(self): """ Start default status spinner. """ if self.ENABLE_SPINNER: self._spinner.start() def stop_spinner(self): """ Stop default status spinner. """ if self.ENABLE_SPINNER: self._spinner.stop() def create_toolbar(self, toolbar_id): """ Create and add an auxiliary toolbar to the top of the plugin. Parameters ---------- toolbar_id: str Unique toolbar string identifier. Returns ------- SpyderPluginToolbar The auxiliary toolbar that was created and added to the plugin interface. """ toolbar = MainWidgetToolbar(parent=self) toolbar.ID = toolbar_id TOOLBAR_REGISTRY.register_reference(toolbar, toolbar_id, self.PLUGIN_NAME, self.CONTEXT_NAME) self._auxiliary_toolbars[toolbar_id] = toolbar self._toolbars_layout.addWidget(toolbar) return toolbar def create_menu(self, menu_id, title='', icon=None): """ Override SpyderMenuMixin method to use a different menu class. Parameters ---------- menu_id: str Unique toolbar string identifier. title: str Toolbar localized title. icon: QIcon or None Icon to use for the menu. Returns ------- MainWidgetMenu The main widget menu. """ menus = getattr(self, '_menus', None) if menus is None: self._menus = OrderedDict() if menu_id in self._menus: raise SpyderAPIError( 'Menu name "{}" already in use!'.format(menu_id)) menu = MainWidgetMenu(parent=self, title=title) menu.ID = menu_id MENU_REGISTRY.register_reference(menu, menu.ID, self.PLUGIN_NAME, self.CONTEXT_NAME) if icon is not None: menu.menuAction().setIconVisibleInMenu(True) menu.setIcon(icon) self._menus[menu_id] = menu return menu def get_options_menu(self): """ Return the main options menu of the widget. """ return self._options_menu def get_options_menu_button(self): """ Return the main options menu button of the widget. """ return self._options_button def get_main_toolbar(self): """ Return the main toolbar of the plugin. Returns ------- QToolBar The main toolbar of the widget that contains the options button. """ return self._main_toolbar def get_auxiliary_toolbars(self): """ Return the auxiliary toolbars of the plugin. Returns ------- OrderedDict A dictionary of wirh toolbar IDs as keys and auxiliary toolbars as values. """ return self._auxiliary_toolbars def set_icon_size(self, icon_size): """ Set the icon size of the plugin's toolbars. Parameters ---------- iconsize: int An integer corresponding to the size in pixels to which the icons of the plugin's toolbars need to be set. """ self._icon_size = icon_size self._main_toolbar.set_icon_size(QSize(icon_size, icon_size)) def show_status_message(self, message, timeout): """ Show a status message in the Spyder widget. """ status_bar = self.statusBar() if status_bar.isVisible(): status_bar.showMessage(message, timeout) def get_focus_widget(self): """ Get the widget to give focus to. Returns ------- QWidget QWidget to give focus to. Notes ----- This is applied when the plugin's dockwidget is raised to the top. """ return self def update_margins(self, margin=None): """ Update central widget margins. """ layout = self.layout() if self._default_margins is None: self._default_margins = layout.getContentsMargins() if margin is not None: layout.setContentsMargins(margin, margin + 3, margin, margin) else: layout.setContentsMargins(*self._default_margins) def update_title(self): """ Update title of dockwidget or plugin window. """ if self.dockwidget is not None: widget = self.dockwidget elif self.windowwidget is not None: widget = self.undocked_window else: return widget.setWindowTitle(self.get_title()) def set_name(self, name): """ Set widget name (plugin.NAME). """ self._name = name def get_name(self): """ Return widget name (plugin.NAME). """ return self._name def set_icon(self, icon): """ Set widget icon. """ self._icon = icon def get_icon(self): """ Return widget icon. """ return self._icon def render_toolbars(self): """ Render all the toolbars of the widget. Notes ----- This action can only be performed once. """ # if not self._toolbars_already_rendered: self._main_toolbar._render() self._corner_toolbar._render() for __, toolbar in self._auxiliary_toolbars.items(): toolbar._render() # self._toolbars_already_rendered = True # --- SpyderDockwidget handling ------------------------------------------ # ------------------------------------------------------------------------ @Slot() def create_window(self): """ Create a QMainWindow instance containing this SpyderWidget. """ # Widgets self.windowwidget = window = SpyderWindowWidget(self) # If the close corner button is used self.windowwidget.sig_closed.connect(self.close_window) # Wigdet setup window.setAttribute(Qt.WA_DeleteOnClose) window.setCentralWidget(self) window.setWindowIcon(self.get_icon()) window.setWindowTitle(self.get_title()) window.resize(self.size()) if self.dockwidget: self.dockwidget.setFloating(False) self.dockwidget.setVisible(False) self.set_ancestor(window) self._update_actions() window.sig_closed.connect(self.close_window) window.show() @Slot() def close_window(self): """ Close QMainWindow instance that contains this SpyderWidget. """ if self.windowwidget is not None: # Fixes spyder-ide/spyder#10704 self.__unsafe_window = self.windowwidget self.__unsafe_window.deleteLater() self.windowwidget.close() self.windowwidget = None # These actions can appear disabled when 'Dock' action is pressed self.undock_action.setDisabled(False) self.close_action.setDisabled(False) if self.dockwidget is not None: self.sig_update_ancestor_requested.emit() self.dockwidget.setWidget(self) self.dockwidget.setVisible(True) self.dockwidget.raise_() self._update_actions() def change_visibility(self, enable, force_focus=None): """ Dock widget visibility has changed. """ is_visible = not self.is_visible if self.dockwidget is None: return if enable: # Avoid double trigger of visibility change self.dockwidget.blockSignals(True) self.dockwidget.raise_() self.dockwidget.blockSignals(False) raise_and_focus = getattr(self, 'RAISE_AND_FOCUS', None) if force_focus is None: if raise_and_focus or not is_visible: focus_widget = self.get_focus_widget() if focus_widget: focus_widget.setFocus() elif force_focus is True: focus_widget = self.get_focus_widget() if focus_widget: focus_widget.setFocus() elif force_focus is False: pass self.is_visible = enable # TODO: Pending on plugin migration that uses this # if getattr(self, 'DISABLE_ACTIONS_WHEN_HIDDEN', None): # for __, action in self.get_actions().items(): # action.setEnabled(is_visible) def toggle_view(self, checked): """ Toggle dockwidget's visibility when its entry is selected in the menu `View > Panes`. Parameters ---------- checked: bool Is the entry in `View > Panes` checked or not? Notes ----- If you need to attach some functionality when this changes, use sig_toggle_view_changed. For an example, please see `spyder/plugins/ipythonconsole/plugin.py` """ if not self.dockwidget: return if checked: self.dockwidget.show() self.dockwidget.raise_() self.is_visible = True else: self.dockwidget.hide() self.is_visible = False # Update toggle view status, if needed, without emitting signals. if self.toggle_view_action.isChecked() != checked: self.blockSignals(True) self.toggle_view_action.setChecked(checked) self.blockSignals(False) self.sig_toggle_view_changed.emit(checked) def create_dockwidget(self, mainwindow): """ Add to parent QMainWindow as a dock widget. """ # Creating dock widget title = self.get_title() self.dockwidget = dock = SpyderDockWidget(title, mainwindow) # Setup dock.setObjectName(self.__class__.__name__ + '_dw') dock.setWidget(self) # Signals dock.visibilityChanged.connect(self.change_visibility) dock.topLevelChanged.connect(self._on_top_level_change) return (dock, dock.LOCATION) @Slot() def close_dock(self): """ Close the dockwidget. """ self.toggle_view(False) # --- API: methods to define or override # ------------------------------------------------------------------------ def get_title(self): """ Return the title that will be displayed on dockwidget or window title. """ raise NotImplementedError('PluginMainWidget must define `get_title`!') def set_ancestor(self, ancestor): """ Needed to update the ancestor/parent of child widgets when undocking. """ pass def setup(self): """ Create widget actions, add to menu and other setup requirements. """ raise NotImplementedError( 'A PluginMainWidget subclass must define a `setup` ' 'method!') def update_actions(self): """ Update the state of exposed actions. Exposed actions are actions created by the self.create_action method. """ raise NotImplementedError( 'A PluginMainWidget subclass must define an `update_actions` ' f'method! Hint: {type(self)} should implement `update_actions`')
def _init_ui(self): # Line 1: Color map self.colormap_label = QLabel("Color Scheme: ") self.colormap_combo = QColormapCombo() self.colormap_combo.addItem("", userData=cm.viridis) self.colormap_combo._update_icons() self.colormap_combo.setCurrentIndex(self._colormap_index) self.colormap_combo.setMaximumWidth(150) self.colormap_combo.currentIndexChanged.connect( self._on_colormap_change) # hbl is short for Horizontal Box Layout hbl1 = QHBoxLayout() hbl1.addWidget(self.colormap_label) hbl1.addWidget(self.colormap_combo) # Line 2: Display contour labels self.contour_label_checkBox = QCheckBox("Contour labels (font size):") if self.contour_settings.add_contour_label: self.contour_label_checkBox.setChecked(True) self.contour_label_checkBox.toggled.connect(self.toggle_labels) font_string = str(self.contour_settings.font_size) self.font_size_input = QLineEdit(font_string) self.font_size_input.setFixedWidth(150) self.font_size_input.setDisabled( not self.contour_settings.add_contour_label) hbl2 = QHBoxLayout() hbl2.addWidget(self.contour_label_checkBox) hbl2.addWidget(self.font_size_input) # Line 3: Contour Spacing self.custom_spacing_checkBox = QCheckBox("Contour spacing (interval):") if self.is_custom_spacing: self.custom_spacing_checkBox.setChecked(True) self.custom_spacing_checkBox.toggled.connect(self.custom_spacing) self.spacing_input = QLineEdit() self.spacing_input.setFixedWidth(150) self.spacing_input.setDisabled(not self.is_custom_spacing) spacing = "" if self.is_custom_spacing: spacing = str(self.contour_settings.spacing) elif self.contour_settings.data_spacing is not None: spacing = self.contour_settings.data_spacing spacing = "{0:1.4f}".format(spacing) self.spacing_default_text = spacing self.spacing_input.setText(spacing) hbl3 = QHBoxLayout() hbl3.addWidget(self.custom_spacing_checkBox) hbl3.addWidget(self.spacing_input) # Line 4: Vmax self.vmax_checkBox = QCheckBox("Set max:") self.vmax_input = QLineEdit() self.vmax_input.setFixedWidth(150) self.vmax_input.setDisabled(not self.is_vmax) vmax = "" if self.is_vmax: self.vmax_checkBox.setChecked(True) vmax = str(self.contour_settings.vmax) elif self.contour_settings.data_max is not None: vmax = self.contour_settings.data_max vmax = "{0:1.4f}".format(vmax) self.vmax_input.setText(vmax) self.vmax_default_text = vmax self.vmax_checkBox.toggled.connect(self.toggle_vmax) hbl4 = QHBoxLayout() hbl4.addWidget(self.vmax_checkBox) hbl4.addWidget(self.vmax_input) # Line 5: Vmin self.vmin_checkBox = QCheckBox("Set min:") self.vmin_input = QLineEdit() self.vmin_input.setFixedWidth(150) self.vmin_input.setDisabled(not self.is_vmin) vmin = "" if self.is_vmin: self.vmin_checkBox.setChecked(True) vmin = str(self.contour_settings.vmin) elif self.contour_settings.data_min is not None: vmin = self.contour_settings.data_min vmin = "{0:1.4f}".format(vmin) self.vmin_input.setText(vmin) self.vmin_default_text = vmin self.vmin_checkBox.toggled.connect(self.toggle_vmin) hbl5 = QHBoxLayout() hbl5.addWidget(self.vmin_checkBox) hbl5.addWidget(self.vmin_input) # Line f: self.previewButton = QPushButton("Preview") self.previewButton.clicked.connect(self.preview) self.defaultButton = QPushButton("Reset") self.defaultButton.clicked.connect(self.default) self.okButton = QPushButton("OK") self.okButton.clicked.connect(self.finish) self.okButton.setDefault(True) self.cancelButton = QPushButton("Cancel") self.cancelButton.clicked.connect(self.cancel) hblf = QHBoxLayout() hblf.addStretch(1) hblf.addWidget(self.previewButton) hblf.addWidget(self.defaultButton) hblf.addWidget(self.cancelButton) hblf.addWidget(self.okButton) vbl = QVBoxLayout() vbl.addLayout(hbl1) vbl.addLayout(hbl2) vbl.addLayout(hbl3) vbl.addLayout(hbl4) vbl.addLayout(hbl5) vbl.addLayout(hblf) self.setLayout(vbl) self.show()
def setupUI(self): width, height = self.determine_dialog_dimensions() self.setFixedSize(width, height) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setWindowTitle("About Mantid Workbench") self.setStyleSheet(f"""QDialog {{ background-color: rgb(190, 230, 190); }} QLabel{{ font: {self.rescale_w(14)}px; }} QPushButton{{ font: {self.rescale_w(14)}px; }} QCommandLinkButton{{ font: {self.rescale_w(22)}px; background-color: rgba(255, 255, 255, 0); border-radius: {self.rescale_w(15)}px; }} QCommandLinkButton:hover {{ background-color: rgba(45, 105, 45, 40); }}""") # version label section at th etop parent_layout = QVBoxLayout() parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(70), vPolicy=QSizePolicy.Fixed)) self.lbl_version.setText("version ") self.lbl_version.setIndent(self.rescale_w(115)) self.lbl_version.setStyleSheet(f"""color: rgb(215, 215, 215); font: {self.rescale_w(28)}pt; font-weight: bold; font-size: {self.rescale_w(28)}px""") parent_layout.addWidget(self.lbl_version) parent_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(40), vPolicy=QSizePolicy.MinimumExpanding)) # split into the two columns two_box_layout = QHBoxLayout() # left side Welcome and Tutorial left_layout = QVBoxLayout() left_layout.setContentsMargins(self.rescale_w(5), 0, self.rescale_w(10), 0) left_layout.setSpacing(0) # welcome label lbl_welcome = QLabel() lbl_welcome.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;") lbl_welcome.setText("Welcome") left_layout.addWidget(lbl_welcome) # release notes self.setup_command_link_button(self.clb_release_notes, "Release Notes", ':/images/Notepad-Bloc-notes-icon-48x48.png') left_layout.addWidget(self.clb_release_notes) # sample datasets self.setup_command_link_button(self.clb_sample_datasets, "Sample Datasets", ':/images/download-icon-48x48.png') left_layout.addWidget(self.clb_sample_datasets) # Tutorials Label lbl_tutorials = QLabel() lbl_tutorials.setStyleSheet(f"color: rgb(45, 105, 45); font-size: {self.rescale_w(28)}px;") lbl_tutorials.setText("Tutorials") left_layout.addWidget(lbl_tutorials) # Mantid Introduction self.setup_command_link_button(self.clb_mantid_introduction, "Mantid Introduction", ':/images/Misc-Tutorial-icon-48x48.png') left_layout.addWidget(self.clb_mantid_introduction) # Introduction to python self.setup_command_link_button(self.clb_python_introduction, "Introduction to Python", ':/images/Python-icon-48x48.png') left_layout.addWidget(self.clb_python_introduction) # Python in Mantid self.setup_command_link_button(self.clb_python_in_mantid, "Python In Mantid", ':/images/Circle_cog_48x48.png') left_layout.addWidget(self.clb_python_in_mantid) # Extending Mantid with python self.setup_command_link_button(self.clb_extending_mantid, "Extending Mantid with Python", ':/images/Plugin-Python-icon-48x48.png') left_layout.addWidget(self.clb_extending_mantid) # right hand side Setup and facility icons right_layout = QVBoxLayout() right_layout.setSpacing(0) # personal setup grp_personal_setup = QGroupBox() grp_personal_setup.setStyleSheet(f"""QGroupBox {{ border: {self.rescale_w(3)}px solid rgb(38, 128, 20);; border-radius: {self.rescale_w(10)}px; background-color: rgb(240, 240, 240); }} QGroupBox QLabel{{ font: {self.rescale_w(12)}px; color: rgb(121, 121, 121); }} QGroupBox QComboBox{{ font: {self.rescale_w(12)}px; }} font: {self.rescale_w(12)}px; """) grp_personal_setup_layout = QVBoxLayout() grp_personal_setup_layout.setContentsMargins(self.rescale_w(9), self.rescale_h(1), self.rescale_w(9), self.rescale_h(9)) grp_personal_setup_layout.setSpacing(0) grp_personal_setup.setLayout(grp_personal_setup_layout) lbl_personal_setup = QLabel() lbl_personal_setup.setStyleSheet(f"color: rgb(38, 128, 20);\nfont-size: {self.rescale_w(18)}px;") lbl_personal_setup.setText("Personal Setup") lbl_personal_setup.setAlignment(Qt.AlignHCenter) grp_personal_setup_layout.addWidget(lbl_personal_setup) personal_setup_form_layout = QFormLayout() personal_setup_form_layout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) personal_setup_form_layout.setHorizontalSpacing(self.rescale_w(5)) personal_setup_form_layout.setVerticalSpacing(self.rescale_h(5)) personal_setup_form_layout.setLabelAlignment(Qt.AlignRight) # default Facility lbl_default_facilty = QLabel() lbl_default_facilty.setText("Default Facility") personal_setup_form_layout.addRow(lbl_default_facilty, self.cb_facility) # default instrument lbl_default_instrument = QLabel() lbl_default_instrument.setText("Default Instrument") personal_setup_form_layout.addRow(lbl_default_instrument, self.cb_instrument) # Set Data Directories lbl_mud = QLabel() lbl_mud.setText("Set data directories") self.pb_manage_user_directories.setText("Manage User Directories") personal_setup_form_layout.addRow(lbl_mud, self.pb_manage_user_directories) # Usage data lbl_allow_usage_data = QLabel() lbl_allow_usage_data.setText("Report Usage Data") usagelayout = QHBoxLayout() usagelayout.setContentsMargins(0, 0, 0, 0) self.chk_allow_usage_data.setChecked(True) self.chk_allow_usage_data.setStyleSheet(f"padding: {self.rescale_w(4)}px;") usagelayout.addWidget(self.chk_allow_usage_data) usagelayout.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) self.lbl_privacy_policy.setText(r'<html><head/><body><p>' r'<a href="https://www.mantidproject.org/MantidProject:Privacy_policy' r'#Usage_Data_recorded_in_Mantid">' r'<span style=" text-decoration: underline; color:#0000ff;">' r'Privacy Policy</span></a></p></body></html>') self.lbl_privacy_policy.setOpenExternalLinks(False) usagelayout.addWidget(self.lbl_privacy_policy) personal_setup_form_layout.addRow(lbl_allow_usage_data, usagelayout) grp_personal_setup_layout.addLayout(personal_setup_form_layout) right_layout.addWidget(grp_personal_setup) right_layout.addSpacerItem(QSpacerItem(self.rescale_w(20), self.rescale_h(40), vPolicy=QSizePolicy.Expanding)) # facility icons # Row one icon_layout_top = QHBoxLayout() icon_layout_top.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_top.setSpacing(0) icon_layout_top.addWidget(self.create_label_with_image(112, 60, ':/images/ISIS_Logo_Transparent_UKRI.png')) icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_top.addWidget(self.create_label_with_image(94, 50, ':/images/ess_logo_transparent_small.png')) icon_layout_top.addSpacerItem(QSpacerItem(self.rescale_w(40), 20, hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_top) # Row two icon_layout_middle = QHBoxLayout() icon_layout_middle.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_middle.setSpacing(0) icon_layout_middle.addWidget(self.create_label_with_image(200, 30, ':/images/Ornl_hfir_sns_logo_small.png')) icon_layout_middle.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_middle) # Row three icon_layout_bottom = QHBoxLayout() icon_layout_bottom.setContentsMargins(0, self.rescale_h(10), 0, 0) icon_layout_bottom.setSpacing(0) icon_layout_bottom.addWidget(self.create_label_with_image(110, 40, ':/images/Tessella_Logo_Transparent.gif')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_bottom.addWidget(self.create_label_with_image(50, 50, ':/images/ILL_logo.png')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) icon_layout_bottom.addWidget(self.create_label_with_image(92, 50, ':/images/CSNS_Logo_Short.png')) icon_layout_bottom.addSpacerItem(QSpacerItem(self.rescale_w(40), self.rescale_h(20), hPolicy=QSizePolicy.Expanding)) right_layout.addLayout(icon_layout_bottom) # end the two box layout two_box_layout.addLayout(left_layout) two_box_layout.addLayout(right_layout) parent_layout.addLayout(two_box_layout) # footer footer_layout = QHBoxLayout() # do not show again do_not_show_layout = QVBoxLayout() do_not_show_layout.setContentsMargins(self.rescale_w(15), 0, 0, 0) do_not_show_layout.setSpacing(self.rescale_w(2)) do_not_show_layout.addSpacerItem(QSpacerItem(1, self.rescale_h(1), vPolicy=QSizePolicy.Expanding)) lbl_update = QLabel() lbl_update.setMinimumSize(self.rescale_w(400), 0) lbl_update.setStyleSheet("color: rgb(25,125,25);") lbl_update.setText('You can revisit this dialog by selecting "About" on the Help menu.') lbl_update.setAlignment(Qt.AlignBottom) do_not_show_layout.addWidget(lbl_update) do_not_show_checkbox_layout = QHBoxLayout() self.chk_do_not_show_until_next_release.setChecked(True) do_not_show_checkbox_layout.addWidget(self.chk_do_not_show_until_next_release) do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(10), self.rescale_h(2), hPolicy=QSizePolicy.Fixed)) lbl_do_not_show = QLabel() lbl_do_not_show.setStyleSheet("color: rgb(25,125,25);") lbl_do_not_show.setText('Do not show again until next release') do_not_show_checkbox_layout.addWidget(lbl_do_not_show) do_not_show_checkbox_layout.addSpacerItem(QSpacerItem(self.rescale_w(40), 10, hPolicy=QSizePolicy.Expanding)) do_not_show_layout.addLayout(do_not_show_checkbox_layout) footer_layout.addLayout(do_not_show_layout) # Close button close_button_layout = QVBoxLayout() close_button_layout.addSpacerItem(QSpacerItem(20, self.rescale_h(15), vPolicy=QSizePolicy.Expanding)) self.pb_close.setText("Close") self.pb_close.setDefault(True) close_button_layout.addWidget(self.pb_close) footer_layout.addLayout(close_button_layout) footer_layout.addSpacerItem(QSpacerItem(self.rescale_w(100), self.rescale_h(20), hPolicy=QSizePolicy.Fixed)) parent_layout.addLayout(footer_layout) self.setLayout(parent_layout) self.setAttribute(Qt.WA_DeleteOnClose, True)
def __init__(self, parent, text, title=None, icon=None, contents_title=None, varname=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) if title is None: title = _("Import wizard") self.setWindowTitle(title) if icon is None: self.setWindowIcon(ima.icon('fileimport')) if contents_title is None: contents_title = _("Raw text") if varname is None: varname = _("variable_name") self.var_name, self.clip_data = None, None # Setting GUI self.tab_widget = QTabWidget(self) self.text_widget = ContentsWidget(self, text) self.table_widget = PreviewWidget(self) self.tab_widget.addTab(self.text_widget, _("text")) self.tab_widget.setTabText(0, contents_title) self.tab_widget.addTab(self.table_widget, _("table")) self.tab_widget.setTabText(1, _("Preview")) self.tab_widget.setTabEnabled(1, False) name_layout = QHBoxLayout() name_label = QLabel(_("Variable Name")) name_layout.addWidget(name_label) self.name_edt = QLineEdit() self.name_edt.setText(varname) name_layout.addWidget(self.name_edt) btns_layout = QHBoxLayout() cancel_btn = QPushButton(_("Cancel")) btns_layout.addWidget(cancel_btn) cancel_btn.clicked.connect(self.reject) h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) btns_layout.addItem(h_spacer) self.back_btn = QPushButton(_("Previous")) self.back_btn.setEnabled(False) btns_layout.addWidget(self.back_btn) self.back_btn.clicked.connect(ft_partial(self._set_step, step=-1)) self.fwd_btn = QPushButton(_("Next")) if not text: self.fwd_btn.setEnabled(False) btns_layout.addWidget(self.fwd_btn) self.fwd_btn.clicked.connect(ft_partial(self._set_step, step=1)) self.done_btn = QPushButton(_("Done")) self.done_btn.setEnabled(False) btns_layout.addWidget(self.done_btn) self.done_btn.clicked.connect(self.process) self.text_widget.asDataChanged.connect(self.fwd_btn.setEnabled) self.text_widget.asDataChanged.connect(self.done_btn.setDisabled) layout = QVBoxLayout() layout.addLayout(name_layout) layout.addWidget(self.tab_widget) layout.addLayout(btns_layout) self.setLayout(layout)
def create_layout(self): """displays the menu objects""" grid = QGridLayout() grid.addWidget(self.title_label, 0, 0) grid.addWidget(self.title_edit, 0, 1) grid.addWidget(self.title_button, 0, 2) grid.addWidget(self.min_label, 1, 0) grid.addWidget(self.min_edit, 1, 1) grid.addWidget(self.min_button, 1, 2) grid.addWidget(self.max_label, 2, 0) grid.addWidget(self.max_edit, 2, 1) grid.addWidget(self.max_button, 2, 2) grid.addWidget(self.format_label, 3, 0) grid.addWidget(self.format_edit, 3, 1) grid.addWidget(self.format_button, 3, 2) grid.addWidget(self.scale_label, 4, 0) grid.addWidget(self.scale_edit, 4, 1) grid.addWidget(self.scale_button, 4, 2) grid.addWidget(self.phase_label, 6, 0) grid.addWidget(self.phase_edit, 6, 1) grid.addWidget(self.phase_button, 6, 2) grid.addWidget(self.arrow_scale_label, 5, 0) grid.addWidget(self.arrow_scale_edit, 5, 1) grid.addWidget(self.arrow_scale_button, 5, 2) grid.addWidget(self.nlabels_label, 7, 0) grid.addWidget(self.nlabels_edit, 7, 1) grid.addWidget(self.nlabels_button, 7, 2) #grid.addWidget(self.labelsize_label, 6, 0) #grid.addWidget(self.labelsize_edit, 6, 1) #grid.addWidget(self.labelsize_button, 6, 2) grid.addWidget(self.ncolors_label, 8, 0) grid.addWidget(self.ncolors_edit, 8, 1) grid.addWidget(self.ncolors_button, 8, 2) grid.addWidget(self.colormap_label, 9, 0) grid.addWidget(self.colormap_edit, 9, 1) grid.addWidget(self.colormap_button, 9, 2) ok_cancel_box = QHBoxLayout() ok_cancel_box.addWidget(self.apply_button) ok_cancel_box.addWidget(self.ok_button) ok_cancel_box.addWidget(self.cancel_button) grid2 = QGridLayout() grid2.addWidget(self.grid2_title, 0, 0) grid2.addWidget(self.low_to_high_radio, 1, 0) grid2.addWidget(self.high_to_low_radio, 2, 0) grid2.addWidget(self.vertical_radio, 1, 1) grid2.addWidget(self.horizontal_radio, 2, 1) grid2.addWidget(self.show_radio, 1, 2) grid2.addWidget(self.hide_radio, 2, 2) grid2.addWidget(self.animate_button, 3, 1) #grid2.setSpacing(0) vbox = QVBoxLayout() vbox.addLayout(grid) #vbox.addLayout(checkboxes) vbox.addLayout(grid2) vbox.addStretch() vbox.addLayout(ok_cancel_box) self.setLayout(vbox)
def __init__(self, parent, max_entries=100): QWidget.__init__(self, parent) self.setWindowTitle("Pylint") self.output = None self.error_output = None self.max_entries = max_entries self.rdata = [] if osp.isfile(self.DATAPATH): try: data = pickle.loads(open(self.DATAPATH, 'rb').read()) if data[0] == self.VERSION: self.rdata = data[1:] except (EOFError, ImportError): pass self.filecombo = PythonModulesComboBox(self) if self.rdata: self.remove_obsolete_items() self.filecombo.addItems(self.get_filenames()) self.start_button = create_toolbutton(self, icon=ima.icon('run'), text=_("Analyze"), tip=_("Run analysis"), triggered=self.start, text_beside_icon=True) self.stop_button = create_toolbutton(self, icon=ima.icon('stop'), text=_("Stop"), tip=_("Stop current analysis"), text_beside_icon=True) self.filecombo.valid.connect(self.start_button.setEnabled) self.filecombo.valid.connect(self.show_data) browse_button = create_toolbutton(self, icon=ima.icon('fileopen'), tip=_('Select Python file'), triggered=self.select_file) self.ratelabel = QLabel() self.datelabel = QLabel() self.log_button = create_toolbutton(self, icon=ima.icon('log'), text=_("Output"), text_beside_icon=True, tip=_("Complete output"), triggered=self.show_log) self.treewidget = ResultsTree(self) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_button) hlayout2 = QHBoxLayout() hlayout2.addWidget(self.ratelabel) hlayout2.addStretch() hlayout2.addWidget(self.datelabel) hlayout2.addStretch() hlayout2.addWidget(self.log_button) layout = QVBoxLayout() layout.addLayout(hlayout1) layout.addLayout(hlayout2) layout.addWidget(self.treewidget) self.setLayout(layout) self.process = None self.set_running_state(False) self.show_data()
def setup_page(self): self.ICON = ima.icon('genprefs') newcb = self.create_checkbox # --- Interface general_group = QGroupBox(_("General")) 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(check_file=True): 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) general_layout = QVBoxLayout() general_layout.addLayout(comboboxes_advanced_layout) general_layout.addWidget(single_instance_box) general_layout.addWidget(prompt_box) general_layout.addWidget(popup_console_box) general_layout.addWidget(check_updates) general_group.setLayout(general_layout) # --- Theme interface_group = QGroupBox(_("Interface")) vertdock_box = newcb(_("Vertical title bars in panes"), 'vertical_dockwidget_titlebars') verttabs_box = newcb(_("Vertical tabs in panes"), 'vertical_tabs') animated_box = newcb(_("Animated toolbars and panes"), 'animated_docks') tear_off_box = newcb(_("Tear off menus"), 'tear_off_menus', tip=_("Set this to detach any<br> " "menu from the main window")) margin_box = newcb(_("Custom margin for panes:"), 'use_custom_margin') margin_spin = self.create_spinbox("", _("pixels"), 'custom_margin', 0, 0, 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(vertdock_box) interface_layout.addWidget(verttabs_box) interface_layout.addWidget(animated_box) interface_layout.addWidget(tear_off_box) interface_layout.addLayout(margins_cursor_layout) interface_group.setLayout(interface_layout) # --- Status bar sbar_group = QGroupBox(_("Status bar")) show_status_bar = newcb(_("Show status bar"), 'show_status_bar') memory_box = newcb(_("Show memory usage every"), 'memory_usage/enable', tip=self.main.mem_status.toolTip()) memory_spin = self.create_spinbox("", _(" ms"), 'memory_usage/timeout', min_=100, max_=1000000, step=100) memory_box.toggled.connect(memory_spin.setEnabled) memory_spin.setEnabled(self.get_option('memory_usage/enable')) memory_box.setEnabled(self.main.mem_status.is_supported()) memory_spin.setEnabled(self.main.mem_status.is_supported()) cpu_box = newcb(_("Show CPU usage every"), 'cpu_usage/enable', tip=self.main.cpu_status.toolTip()) cpu_spin = self.create_spinbox("", _(" ms"), 'cpu_usage/timeout', min_=100, max_=1000000, step=100) cpu_box.toggled.connect(cpu_spin.setEnabled) cpu_spin.setEnabled(self.get_option('cpu_usage/enable')) cpu_box.setEnabled(self.main.cpu_status.is_supported()) cpu_spin.setEnabled(self.main.cpu_status.is_supported()) status_bar_o = self.get_option('show_status_bar') show_status_bar.toggled.connect(memory_box.setEnabled) show_status_bar.toggled.connect(memory_spin.setEnabled) show_status_bar.toggled.connect(cpu_box.setEnabled) show_status_bar.toggled.connect(cpu_spin.setEnabled) memory_box.setEnabled(status_bar_o) memory_spin.setEnabled(status_bar_o) cpu_box.setEnabled(status_bar_o) cpu_spin.setEnabled(status_bar_o) # Layout status bar cpu_memory_layout = QGridLayout() cpu_memory_layout.addWidget(memory_box, 0, 0) cpu_memory_layout.addWidget(memory_spin, 0, 1) cpu_memory_layout.addWidget(cpu_box, 1, 0) cpu_memory_layout.addWidget(cpu_spin, 1, 1) sbar_layout = QVBoxLayout() sbar_layout.addWidget(show_status_bar) sbar_layout.addLayout(cpu_memory_layout) sbar_group.setLayout(sbar_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) 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(custom_scaling_edit.setDisabled) auto_scale_radio.toggled.connect(custom_scaling_edit.setDisabled) custom_scaling_radio.toggled.connect(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(custom_scaling_edit, 2, 1) screen_resolution_layout.addLayout(screen_resolution_inner_layout) screen_resolution_group.setLayout(screen_resolution_layout) tabs = QTabWidget() tabs.addTab(self.create_tab(screen_resolution_group, interface_group), _("Interface")) tabs.addTab(self.create_tab(general_group, sbar_group), _("Advanced settings")) vlayout = QVBoxLayout() vlayout.addWidget(tabs) self.setLayout(vlayout)
def setup(self, check_all=None, exclude_private=None, exclude_uppercase=None, exclude_capitalized=None, exclude_unsupported=None, excluded_names=None, truncate=None, minmax=None, remote_editing=None, autorefresh=None): """Setup the namespace browser""" assert self.shellwidget is not None self.check_all = check_all self.exclude_private = exclude_private self.exclude_uppercase = exclude_uppercase self.exclude_capitalized = exclude_capitalized self.exclude_unsupported = exclude_unsupported self.excluded_names = excluded_names self.truncate = truncate self.minmax = minmax self.remote_editing = remote_editing self.autorefresh = autorefresh if self.editor is not None: self.editor.setup_menu(truncate, minmax) self.exclude_private_action.setChecked(exclude_private) self.exclude_uppercase_action.setChecked(exclude_uppercase) self.exclude_capitalized_action.setChecked(exclude_capitalized) self.exclude_unsupported_action.setChecked(exclude_unsupported) # Don't turn autorefresh on for IPython kernels # See Issue 1450 if not self.is_ipykernel: self.auto_refresh_button.setChecked(autorefresh) self.refresh_table() return # Dict editor: if self.is_internal_shell: self.editor = CollectionsEditorTableView(self, None, truncate=truncate, minmax=minmax) else: self.editor = RemoteCollectionsEditorTableView( self, None, truncate=truncate, minmax=minmax, remote_editing=remote_editing, get_value_func=self.get_value, set_value_func=self.set_value, new_value_func=self.set_value, remove_values_func=self.remove_values, copy_value_func=self.copy_value, is_list_func=self.is_list, get_len_func=self.get_len, is_array_func=self.is_array, is_image_func=self.is_image, is_dict_func=self.is_dict, is_data_frame_func=self.is_data_frame, is_series_func=self.is_series, get_array_shape_func=self.get_array_shape, get_array_ndim_func=self.get_array_ndim, oedit_func=self.oedit, plot_func=self.plot, imshow_func=self.imshow, show_image_func=self.show_image) self.editor.sig_option_changed.connect(self.sig_option_changed.emit) self.editor.sig_files_dropped.connect(self.import_data) # Setup layout layout = QVBoxLayout() blayout = QHBoxLayout() toolbar = self.setup_toolbar(exclude_private, exclude_uppercase, exclude_capitalized, exclude_unsupported, autorefresh) for widget in toolbar: blayout.addWidget(widget) # Options menu options_button = create_toolbutton(self, text=_('Options'), icon=ima.icon('tooloptions')) options_button.setPopupMode(QToolButton.InstantPopup) menu = QMenu(self) editor = self.editor actions = [ self.exclude_private_action, self.exclude_uppercase_action, self.exclude_capitalized_action, self.exclude_unsupported_action, None, editor.truncate_action ] if is_module_installed('numpy'): actions.append(editor.minmax_action) add_actions(menu, actions) options_button.setMenu(menu) blayout.addStretch() blayout.addWidget(options_button) layout.addLayout(blayout) layout.addWidget(self.editor) self.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) self.sig_option_changed.connect(self.option_changed)
class QtAbout(QDialog): def __init__(self): super().__init__() self.layout = QVBoxLayout() # Description title_label = QLabel( "<b>napari: a multi-dimensional image viewer for python</b>") title_label.setTextInteractionFlags(Qt.TextSelectableByMouse) self.layout.addWidget(title_label) # Add information self.infoTextBox = QTextEdit() self.infoTextBox.setTextInteractionFlags(Qt.TextSelectableByMouse) self.infoTextBox.setLineWrapMode(QTextEdit.NoWrap) # Add text copy button self.infoCopyButton = QtCopyToClipboardButton(self.infoTextBox) self.info_layout = QHBoxLayout() self.info_layout.addWidget(self.infoTextBox, 1) self.info_layout.addWidget(self.infoCopyButton, 0, Qt.AlignTop) self.info_layout.setAlignment(Qt.AlignTop) self.layout.addLayout(self.info_layout) if API_NAME == 'PySide2': API_VERSION = PYSIDE_VERSION elif API_NAME == 'PyQt5': API_VERSION = PYQT_VERSION else: API_VERSION = '' sys_version = sys.version.replace('\n', ' ') versions = (f"<b>napari</b>: {napari.__version__} <br>" f"<b>Platform</b>: {platform.platform()} <br>" f"<b>Python</b>: {sys_version} <br>" f"<b>{API_NAME}</b>: {API_VERSION} <br>" f"<b>Qt</b>: {QtCore.__version__} <br>" f"<b>VisPy</b>: {vispy.__version__} <br>" f"<b>NumPy</b>: {numpy.__version__} <br>" f"<b>SciPy</b>: {scipy.__version__} <br>" f"<b>scikit-image</b>: {skimage.__version__} <br>" f"<b>Dask</b>: {dask.__version__} <br>") sys_info_text = "<br>".join( [vispy.sys_info().split("\n")[index] for index in [-4, -3]]) text = f'{versions} <br> {sys_info_text} <br>' self.infoTextBox.setText(text) self.layout.addWidget(QLabel('<b>citation information:</b>')) citation_text = ('napari contributors (2019). napari: a ' 'multi-dimensional image viewer for python. ' 'doi:10.5281/zenodo.3555620') self.citationTextBox = QTextEdit(citation_text) self.citationTextBox.setFixedHeight(64) self.citationCopyButton = QtCopyToClipboardButton(self.citationTextBox) self.citation_layout = QHBoxLayout() self.citation_layout.addWidget(self.citationTextBox, 1) self.citation_layout.addWidget(self.citationCopyButton, 0, Qt.AlignTop) self.layout.addLayout(self.citation_layout) self.setLayout(self.layout) @staticmethod def showAbout(qt_viewer): d = QtAbout() d.setObjectName('QtAbout') d.setStyleSheet(qt_viewer.styleSheet()) d.setWindowTitle('About') d.setWindowModality(Qt.ApplicationModal) d.exec_()
def __init__(self, parent, context, name, sequence, shortcuts): super(ShortcutEditor, self).__init__(parent) self._parent = parent self.context = context self.npressed = 0 self.keys = set() self.key_modifiers = set() self.key_non_modifiers = list() self.key_text = list() self.sequence = sequence self.new_sequence = None self.edit_state = True self.shortcuts = shortcuts # Widgets self.label_info = QLabel() self.label_info.setText(_("Press the new shortcut and select 'Ok': \n" "(Press 'Tab' once to switch focus between the shortcut entry \n" "and the buttons below it)")) self.label_current_sequence = QLabel(_("Current shortcut:")) self.text_current_sequence = QLabel(sequence) self.label_new_sequence = QLabel(_("New shortcut:")) self.text_new_sequence = CustomLineEdit(self) self.text_new_sequence.setPlaceholderText(sequence) self.helper_button = HelperToolButton() self.helper_button.hide() self.label_warning = QLabel() self.label_warning.hide() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = bbox.button(QDialogButtonBox.Ok) self.button_cancel = bbox.button(QDialogButtonBox.Cancel) # Setup widgets self.setWindowTitle(_('Shortcut: {0}').format(name)) self.button_ok.setFocusPolicy(Qt.NoFocus) self.button_ok.setEnabled(False) self.button_cancel.setFocusPolicy(Qt.NoFocus) self.helper_button.setToolTip('') self.helper_button.setFocusPolicy(Qt.NoFocus) style = """ QToolButton { margin:1px; border: 0px solid grey; padding:0px; border-radius: 0px; }""" self.helper_button.setStyleSheet(style) self.text_new_sequence.setFocusPolicy(Qt.NoFocus) self.label_warning.setFocusPolicy(Qt.NoFocus) # Layout spacing = 5 layout_sequence = QGridLayout() layout_sequence.addWidget(self.label_info, 0, 0, 1, 3) layout_sequence.addItem(QSpacerItem(spacing, spacing), 1, 0, 1, 2) layout_sequence.addWidget(self.label_current_sequence, 2, 0) layout_sequence.addWidget(self.text_current_sequence, 2, 2) layout_sequence.addWidget(self.label_new_sequence, 3, 0) layout_sequence.addWidget(self.helper_button, 3, 1) layout_sequence.addWidget(self.text_new_sequence, 3, 2) layout_sequence.addWidget(self.label_warning, 4, 2, 1, 2) layout = QVBoxLayout() layout.addLayout(layout_sequence) layout.addSpacing(spacing) layout.addWidget(bbox) self.setLayout(layout) # Signals bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject)
def __init__(self, parent): QWidget.__init__(self, parent) self.setWindowTitle("Memory profiler") self.output = None self.error_output = None self.use_colors = True self._last_wdir = None self._last_args = None self._last_pythonpath = None self.filecombo = PythonModulesComboBox(self) self.start_button = create_toolbutton(self, icon=get_icon('run.png'), text=_("Profile memory usage"), tip=_("Run memory profiler"), triggered=self.start, text_beside_icon=True) self.stop_button = create_toolbutton(self, icon=get_icon('terminate.png'), 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=get_icon('fileopen.png'), tip=_('Select Python script'), triggered=self.select_file) self.datelabel = QLabel() self.log_button = create_toolbutton(self, icon=get_icon('log.png'), text=_("Output"), text_beside_icon=True, tip=_("Show program's output"), triggered=self.show_log) self.datatree = MemoryProfilerDataTree(self) self.collapse_button = create_toolbutton( self, icon=get_icon('collapse.png'), triggered=lambda dD=-1: self.datatree.collapseAll(), tip=_('Collapse all')) self.expand_button = create_toolbutton( self, icon=get_icon('expand.png'), triggered=lambda dD=1: self.datatree.expandAll(), tip=_('Expand all')) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.filecombo) hlayout1.addWidget(browse_button) hlayout1.addWidget(self.start_button) hlayout1.addWidget(self.stop_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) 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) if not is_memoryprofiler_installed(): for widget in (self.datatree, self.filecombo, self.log_button, self.start_button, self.stop_button, browse_button, self.collapse_button, self.expand_button): widget.setDisabled(True) text = _( '<b>Please install the <a href="%s">memory_profiler module</a></b>' ) % WEBSITE_URL self.datelabel.setText(text) self.datelabel.setOpenExternalLinks(True) else: pass # self.show_data()