def __init__(self, *args, **kwargs): self.sphinx_dir = kwargs.pop('sphinx_dir', mkdtemp()) self.build_dir = osp.join(self.sphinx_dir, '_build', 'html') super(UrlHelp, self).__init__(*args, **kwargs) self.error_msg = PyErrorMessage(self) if with_sphinx: self.sphinx_thread = SphinxThread(self.sphinx_dir) self.sphinx_thread.html_ready[str].connect(self.browse) self.sphinx_thread.html_error[str].connect( self.error_msg.showTraceback) self.sphinx_thread.html_error[str].connect(logger.debug) rcParams.connect('help_explorer.render_docs_parallel', self.reset_sphinx) rcParams.connect('help_explorer.use_intersphinx', self.reset_sphinx) rcParams.connect('help_explorer.online', self.reset_sphinx) else: self.sphinx_thread = None self.bt_connect_console = QToolButton(self) self.bt_connect_console.setCheckable(True) if rcParams['console.connect_to_help']: self.bt_connect_console.setIcon( QIcon(get_icon('ipython_console.png'))) self.bt_connect_console.click() else: self.bt_connect_console.setIcon( QIcon(get_icon('ipython_console_t.png'))) self.bt_connect_console.clicked.connect(self.toogle_connect_console) rcParams.connect('console.connect_to_help', self.update_connect_console) self.toogle_connect_console() # menu button with different urls self.bt_url_menus = QToolButton(self) self.bt_url_menus.setIcon(QIcon(get_icon('docu_button.png'))) self.bt_url_menus.setToolTip('Browse documentations') self.bt_url_menus.setPopupMode(QToolButton.InstantPopup) docu_menu = QMenu(self) for name, url in six.iteritems(self.doc_urls): def to_url(b, url=url): self.browse(url) action = QAction(name, self) action.triggered.connect(to_url) docu_menu.addAction(action) self.bt_url_menus.setMenu(docu_menu) self.button_box.addWidget(self.bt_connect_console) self.button_box.addWidget(self.bt_url_menus) # toogle the lock again to set the bt_url_menus enabled state self.toogle_url_lock()
def initialize(self): """Fill the items of the :attr:`rc` into the tree""" rcParams = self.rc descriptions = self.descriptions self.valid = [True] * len(rcParams) validators = self.validators vcol = self.value_col for i, (key, val) in enumerate(sorted(rcParams.items())): item = QTreeWidgetItem(0) item.setText(0, key) item.setToolTip(0, key) item.setIcon(1, QIcon(get_icon('valid.png'))) desc = descriptions.get(key) if desc: item.setText(vcol, desc) item.setToolTip(vcol, desc) child = QTreeWidgetItem(0) item.addChild(child) self.addTopLevelItem(item) editor = QTextEdit(self) # set maximal height of the editor to 3 rows editor.setMaximumHeight(4 * QtGui.QFontMetrics(editor.font()).height()) editor.setPlainText(yaml.dump(val)) self.setItemWidget(child, vcol, editor) editor.textChanged.connect( self.set_icon_func(i, item, validators[key])) self.resizeColumnToContents(0) self.resizeColumnToContents(1)
def __init__(self, parent, fname=None, rst=None, name=None): """ Parameters ---------- parent: QWidget The parent widget fname: str The name of the rst file. If None, specify the `rst` directly rst: str The restructured text to render when this button is clicked. If None, the `fname` has to be provided name: str The name to use for the document in the help_explorer """ if fname is None and rst is None: raise ValueError("Either `fname` or `rst` must be specified!") elif fname is not None and rst is not None: raise ValueError("Either `fname` or `rst` must be specified! " "Not both!") elif rst is not None and name is None: raise ValueError("A title must be specified for the rst document!") self.fname = fname self.rst = rst self.files = doc_files self.name = name QToolButton.__init__(self, parent) self.setIcon(QIcon(get_psy_icon('info.png'))) self.clicked.connect(self.show_docs)
def set_col_wand_mode(self): """Set the current wand tool to the color wand""" self.wand_type = 'cols' self.wand_action.setIcon(QIcon(get_icon('col_select.png'))) for a in self.color_wand_actions: a.setVisible(False) self._action_clicked = None self.toggle_selection()
def toogle_connect_console(self): """Disable (or enable) the loading of web pages in www""" bt = self.bt_connect_console connect = bt.isChecked() bt.setIcon(QIcon(get_icon( 'ipython_console.png' if connect else 'ipython_console_t.png'))) bt.setToolTip("%sonnect the console to the help explorer" % ( "Don't c" if connect else "C")) if rcParams['console.connect_to_help'] is not connect: rcParams['console.connect_to_help'] = connect
def trigger_plot_btn(): a = next(iter(get_artists()), None) if a is None: if can_be_plotted is None or can_be_plotted(): plot_func() cb.setChecked(True) btn.setIcon(QIcon(get_icon('invalid.png'))) btn.setToolTip('Remove ' + what) self.draw_figs(get_artists()) cb.setEnabled(True) else: fig = a.axes.figure figs = {a.axes.figure for a in get_artists()} remove_func() btn.setIcon(QIcon(get_icon('valid.png'))) btn.setToolTip('Show ' + what) for fig in figs: fig.canvas.draw_idle() cb.setEnabled(False)
def func(): editor = self.itemWidget(item.child(0), self.value_col) s = asstring(editor.toPlainText()) try: val = yaml.load(s, Loader=yaml.Loader) except Exception as e: item.setIcon(1, QIcon(get_icon('warning.png'))) item.setToolTip(1, "Could not parse yaml code: %s" % e) self.set_valid(i, False) return try: validator(val) except Exception as e: item.setIcon(1, QIcon(get_icon('invalid.png'))) item.setToolTip(1, "Wrong value: %s" % e) self.set_valid(i, False) else: item.setIcon(1, QIcon(get_icon('valid.png'))) self.set_valid(i, True) self.propose_changes.emit(self.parent() or self)
def refresh(self): for row, (what, func) in enumerate(self.get_artists_funcs.items()): a = next(iter(func()), None) cb = self.cellWidget(row, 0) cb.setEnabled(a is not None) if a is not None: cb.setChecked(Qt.Checked if a.get_visible() else Qt.Unchecked) btn = self.cellWidget(row, 1) if btn is not None: can_be_plotted = self.can_be_plotted_funcs[what] if can_be_plotted is None or can_be_plotted(): if a is not None: btn.setIcon(QIcon(get_icon('invalid.png'))) btn.setToolTip('Remove ' + what) else: btn.setIcon(QIcon(get_icon('valid.png'))) btn.setToolTip('Show ' + what) btn.setEnabled(True) else: btn.setEnabled(False)
def add_toolbar_widgets(self, mark): """Add the navigation actions to the toolbar""" tb = self.straditizer.marks[0].ax.figure.canvas.toolbar if not isinstance(tb, QToolBar): return if self.tb_actions: self.remove_actions() self.tb_actions.append(tb.addSeparator()) try: mark.x except NotImplementedError: add_right = False else: a = tb.addAction(QIcon(get_icon('left_mark.png')), 'left mark', self.go_to_left_mark) a.setToolTip('Move to the next cross mark on the left') self.tb_actions.append(a) add_right = True try: mark.y except NotImplementedError: pass else: a = tb.addAction(QIcon(get_icon('upper_mark.png')), 'upper mark', self.go_to_upper_mark) a.setToolTip('Move to the next cross mark above') self.tb_actions.append(a) a = tb.addAction(QIcon(get_icon('lower_mark.png')), 'lower mark', self.go_to_lower_mark) a.setToolTip('Move to the next cross mark below') self.tb_actions.append(a) if add_right: a = tb.addAction(QIcon(get_icon('right_mark.png')), 'right mark', self.go_to_right_mark) a.setToolTip('Move to the next cross mark on the right') self.tb_actions.append(a) self._toolbar = tb
def toogle_url_lock(self): """Disable (or enable) the loading of web pages in www""" bt = self.bt_url_lock offline = bt.isChecked() bt.setIcon(QIcon( get_icon('world_red.png' if offline else 'world.png'))) online_message = "Go online" if not with_qt5: online_message += ("\nWARNING: This mode is unstable under Qt4 " "and might result in a complete program crash!") bt.setToolTip(online_message if offline else "Offline mode") if rcParams['help_explorer.online'] is offline: rcParams['help_explorer.online'] = not offline
def __init__(self, df, straditizer, fname=None, *args, **kwargs): """ Parameters ---------- df: pandas.DataFrame The DataFrame to be exported straditizer: straditize.straditizer.Straditizer The source straditizer fname: str The file name to export to """ super().__init__(*args, **kwargs) self.df = df self.stradi = straditizer self.txt_fname = QLineEdit() self.bt_open_file = QToolButton() self.bt_open_file.setIcon(QIcon(get_icon('run_arrow.png'))) self.bt_open_file.setToolTip('Select the export file on your drive') self.cb_include_meta = QCheckBox('Include meta data') self.cb_include_meta.setChecked(True) self.bbox = bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) # --------------------------------------------------------------------- # --------------------------- Layouts --------------------------------- # --------------------------------------------------------------------- vbox = QVBoxLayout() hbox = QHBoxLayout() hbox.addWidget(QLabel('Export to:')) hbox.addWidget(self.txt_fname) hbox.addWidget(self.bt_open_file) vbox.addLayout(hbox) vbox.addWidget(self.cb_include_meta) vbox.addWidget(bbox) self.setLayout(vbox) # --------------------------------------------------------------------- # --------------------------- Connections ----------------------------- # --------------------------------------------------------------------- bbox.accepted.connect(self._export) bbox.rejected.connect(self.reject) self.bt_open_file.clicked.connect(self.get_open_file_name) if fname is not None: self.txt_fname.setText(fname) self._export()
def __init__(self, instances=None, *args, **kwargs): """ Parameters ---------- instances: class or tuple of classes The classes that should be used for an instance check """ super(LoadFromConsoleButton, self).__init__(*args, **kwargs) self.setIcon(QIcon(get_icon('console-go.png'))) if instances is not None and inspect.isclass(instances): instances = (instances, ) self._instances2check = instances self.error_msg = PyErrorMessage(self) self.clicked.connect(partial(self.get_from_shell, None))
def __init__(self, *args, **kwargs): """ Parameters ---------- help_explorer: psyplot_gui.help_explorer.HelpExplorer The help explorer to show the documentation of one formatoption console: psyplot_gui.console.ConsoleWidget The console that can be used to update the current subproject via:: psy.gcp().update(**kwargs) where ``**kwargs`` is defined through the selected formatoption in the :attr:`fmt_combo` combobox and the value in the :attr:`line_edit` editor ``*args, **kwargs`` Any other keyword for the QWidget class """ help_explorer = kwargs.pop('help_explorer', None) console = kwargs.pop('console', None) super(FormatoptionWidget, self).__init__(*args, **kwargs) self.help_explorer = help_explorer self.console = console self.error_msg = PyErrorMessage(self) # --------------------------------------------------------------------- # -------------------------- Child widgets ---------------------------- # --------------------------------------------------------------------- self.group_combo = QComboBox(parent=self) self.fmt_combo = QComboBox(parent=self) self.line_edit = QLineEdit(parent=self) self.text_edit = QTextEdit(parent=self) self.run_button = QToolButton(parent=self) # completer for the fmto widget self.fmt_combo.setEditable(True) self.fmt_combo.setInsertPolicy(QComboBox.NoInsert) self.fmto_completer = completer = QCompleter( ['time', 'lat', 'lon', 'lev']) completer.setCompletionMode(QCompleter.PopupCompletion) completer.activated[str].connect(self.set_fmto) if with_qt5: completer.setFilterMode(Qt.MatchContains) completer.setModel(QStandardItemModel()) self.fmt_combo.setCompleter(completer) self.dim_widget = DimensionsWidget(parent=self) self.dim_widget.setVisible(False) self.multiline_button = QPushButton('Multiline', parent=self) self.multiline_button.setCheckable(True) self.yaml_cb = QCheckBox('Yaml syntax') self.yaml_cb.setChecked(True) self.keys_button = QPushButton('Keys', parent=self) self.summaries_button = QPushButton('Summaries', parent=self) self.docs_button = QPushButton('Docs', parent=self) self.grouped_cb = QCheckBox('grouped', parent=self) self.all_groups_cb = QCheckBox('all groups', parent=self) self.include_links_cb = QCheckBox('include links', parent=self) self.text_edit.setVisible(False) # --------------------------------------------------------------------- # -------------------------- Descriptions ----------------------------- # --------------------------------------------------------------------- self.group_combo.setToolTip('Select the formatoption group') self.fmt_combo.setToolTip('Select the formatoption to update') self.line_edit.setToolTip( 'Insert the value which what you want to update the selected ' 'formatoption and hit right button. The code is executed in the ' 'main console.') self.yaml_cb.setToolTip( "Use the yaml syntax for the values inserted in the above cell. " "Otherwise the content there is evaluated as a python expression " "in the terminal") self.text_edit.setToolTip(self.line_edit.toolTip()) self.run_button.setIcon(QIcon(get_icon('run_arrow.png'))) self.run_button.setToolTip('Update the selected formatoption') self.multiline_button.setToolTip( 'Allow linebreaks in the text editor line above.') self.keys_button.setToolTip( 'Show the formatoption keys in this group (or in all ' 'groups) in the help explorer') self.summaries_button.setToolTip( 'Show the formatoption summaries in this group (or in all ' 'groups) in the help explorer') self.docs_button.setToolTip( 'Show the formatoption documentations in this group (or in all ' 'groups) in the help explorer') self.grouped_cb.setToolTip( 'Group the formatoptions before displaying them in the help ' 'explorer') self.all_groups_cb.setToolTip('Use all groups when displaying the ' 'keys, docs or summaries') self.include_links_cb.setToolTip( 'Include links to remote documentations when showing the ' 'keys, docs and summaries in the help explorer (requires ' 'intersphinx)') # --------------------------------------------------------------------- # -------------------------- Connections ------------------------------ # --------------------------------------------------------------------- self.group_combo.currentIndexChanged[int].connect(self.fill_fmt_combo) self.fmt_combo.currentIndexChanged[int].connect(self.show_fmt_info) self.fmt_combo.currentIndexChanged[int].connect(self.load_fmt_widget) self.fmt_combo.currentIndexChanged[int].connect( self.set_current_fmt_value) self.run_button.clicked.connect(self.run_code) self.line_edit.returnPressed.connect(self.run_button.click) self.multiline_button.clicked.connect(self.toggle_line_edit) self.keys_button.clicked.connect( partial(self.show_all_fmt_info, 'keys')) self.summaries_button.clicked.connect( partial(self.show_all_fmt_info, 'summaries')) self.docs_button.clicked.connect( partial(self.show_all_fmt_info, 'docs')) # --------------------------------------------------------------------- # ------------------------------ Layouts ------------------------------ # --------------------------------------------------------------------- self.combos = QHBoxLayout() self.combos.addWidget(self.group_combo) self.combos.addWidget(self.fmt_combo) self.execs = QHBoxLayout() self.execs.addWidget(self.line_edit) self.execs.addWidget(self.text_edit) self.execs.addWidget(self.run_button) self.info_box = QHBoxLayout() self.info_box.addWidget(self.multiline_button) self.info_box.addWidget(self.yaml_cb) self.info_box.addStretch(0) for w in [ self.keys_button, self.summaries_button, self.docs_button, self.all_groups_cb, self.grouped_cb, self.include_links_cb ]: self.info_box.addWidget(w) self.vbox = QVBoxLayout() self.vbox.addLayout(self.combos) self.vbox.addWidget(self.dim_widget) self.vbox.addLayout(self.execs) self.vbox.addLayout(self.info_box) self.vbox.setSpacing(0) self.setLayout(self.vbox) # fill with content self.fill_combos_from_project(psy.gcp()) psy.Project.oncpchange.connect(self.fill_combos_from_project) rcParams.connect('fmt.sort_by_key', self.refill_from_rc)
def toogle_lock(self): """Disable (or enable) the changing of the current webpage""" bt = self.bt_lock bt.setIcon( QIcon(get_icon('lock.png' if bt.isChecked() else 'lock_open.png'))) bt.setToolTip("Unlock" if bt.isChecked() else "Lock to current page")
def __init__(self, *args, **kwargs): super(UrlBrowser, self).__init__(*args, **kwargs) # --------------------------------------------------------------------- # ---------------------------- upper buttons -------------------------- # --------------------------------------------------------------------- # adress line self.tb_url = UrlCombo(self) # button to go to previous url self.bt_back = QToolButton(self) # button to go to next url self.bt_ahead = QToolButton(self) # refresh the current url self.bt_refresh = QToolButton(self) # button to go lock to the current url self.bt_lock = QToolButton(self) # button to disable browsing in www self.bt_url_lock = QToolButton(self) # ---------------------------- buttons settings ----------------------- self.bt_back.setIcon(QIcon(get_icon('previous.png'))) self.bt_back.setToolTip('Go back one page') self.bt_ahead.setIcon(QIcon(get_icon('next.png'))) self.bt_back.setToolTip('Go forward one page') self.bt_refresh.setIcon(QIcon(get_icon('refresh.png'))) self.bt_refresh.setToolTip('Refresh the current page') self.bt_lock.setCheckable(True) self.bt_url_lock.setCheckable(True) if not with_qt5 and rcParams['help_explorer.online'] is None: # We now that the browser can crash with Qt4, therefore we disable # the browing in the internet self.bt_url_lock.click() rcParams['help_explorer.online'] = False elif rcParams['help_explorer.online'] is False: self.bt_url_lock.click() elif rcParams['help_explorer.online'] is None: rcParams['help_explorer.online'] = True rcParams.connect('help_explorer.online', self.update_url_lock_from_rc) self.bt_url_lock.clicked.connect(self.toogle_url_lock) self.bt_lock.clicked.connect(self.toogle_lock) # tooltip and icons of lock and url_lock are set in toogle_lock and # toogle_url_lock self.toogle_lock() self.toogle_url_lock() # --------------------------------------------------------------------- # --------- initialization and connection of the web view ------------- # --------------------------------------------------------------------- #: The actual widget showing the html content self.html = QWebEngineView(parent=self) self.html.loadStarted.connect(self.completed) self.html.loadFinished.connect(self.completed) self.tb_url.currentIndexChanged[str].connect(self.browse) self.bt_back.clicked.connect(self.html.back) self.bt_ahead.clicked.connect(self.html.forward) self.bt_refresh.clicked.connect(self.html.reload) self.html.urlChanged.connect(self.url_changed) # --------------------------------------------------------------------- # ---------------------------- layouts -------------------------------- # --------------------------------------------------------------------- # The upper part of the browser containing all the buttons self.button_box = button_box = QHBoxLayout() button_box.addWidget(self.bt_back) button_box.addWidget(self.bt_ahead) button_box.addWidget(self.tb_url) button_box.addWidget(self.bt_refresh) button_box.addWidget(self.bt_lock) button_box.addWidget(self.bt_url_lock) # The upper most layout aranging the button box and the html widget self.vbox = vbox = QVBoxLayout() self.vbox.setContentsMargins(0, 0, 0, 0) vbox.addLayout(button_box) vbox.addWidget(self.html) self.setLayout(vbox) if self.default_url is not None: self.tb_url.addItem(self.default_url)
def __init__(self, parent, fmto, artist=None, base=None): """ Parameters ---------- %(FontWeightWidget.parameters)s """ QWidget.__init__(self, parent) hbox = QHBoxLayout() if artist is not None: self.current_font = self.artist_to_qfont(artist) self.current_color = QtGui.QColor.fromRgbF( *mcol.to_rgba(artist.get_color())) else: self.current_color = QtGui.QColor(Qt.black) self.fmto_name = fmto.name or fmto.key # choose font button button = QPushButton('Choose font') button.clicked.connect(partial(self.choose_font, None)) hbox.addWidget(button) # font size spin box self.spin_box = spin_box = QSpinBox(self) spin_box.setRange(1, 1e9) if artist is not None: spin_box.setValue(int(artist.get_size())) spin_box.valueChanged.connect(self.modify_size) hbox.addWidget(spin_box) # font color button self.btn_font_color = button = QToolButton(self) button.setIcon(QIcon(get_icon('font_color.png'))) button.clicked.connect(partial(self.choose_color, None)) hbox.addWidget(button) # bold button self.btn_bold = button = QToolButton(self) button.setIcon(QIcon(get_icon('bold.png'))) button.clicked.connect(self.toggle_bold) button.setCheckable(True) if artist is not None: button.setChecked(self.current_font.weight() > 50) hbox.addWidget(button) # italic button self.btn_italic = button = QToolButton(self) button.setIcon(QIcon(get_icon('italic.png'))) button.clicked.connect(self.toggle_italic) button.setCheckable(True) if artist is not None: button.setChecked(self.current_font.italic()) hbox.addWidget(button) if base is not None: # add a button to change to the base formatoption fmtos = [ base, getattr(fmto.plotter, base.key + 'size', None), getattr(fmto.plotter, base.key + 'weight', None), ] fmtos = list(filter(None, fmtos)) hbox.addWidget(Switch2FmtButton(parent, *fmtos)) self.setLayout(hbox)
def create_actions(self): """Define the actions for the toolbar and set everything up""" # Reader toolbar self.combo = QComboBox() self.combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.addWidget(self.combo) select_group = QActionGroup(self) # select action self._actions['select'] = a = self.addAction( QIcon(get_icon('select.png')), 'select', self.toggle_selection) a.setToolTip('Select pixels within a rectangle') a.setCheckable(True) select_group.addAction(a) # select menu select_menu = QMenu(self) self._select_actions['rect_select'] = menu_a = select_menu.addAction( QIcon(get_icon('select.png')), 'rectangle', self.set_rect_select_mode) menu_a.setToolTip('Select a rectangle') a.setToolTip(menu_a.toolTip()) self._select_actions['poly_select'] = menu_a = select_menu.addAction( QIcon(get_icon('poly_select.png')), 'polygon', self.set_poly_select_mode) menu_a.setToolTip('Select a rectangle') a.setToolTip(menu_a.toolTip()) a.setMenu(select_menu) # wand_select action self._actions['wand_select'] = a = self.addAction( QIcon(get_icon('wand_select.png')), 'select', self.toggle_selection) a.setCheckable(True) select_group.addAction(a) # wand menu tool_menu = QMenu(self) self._wand_actions['wand_select'] = menu_a = tool_menu.addAction( QIcon(get_icon('wand_select.png')), 'wand', self.set_label_wand_mode) menu_a.setToolTip('Select labels within a rectangle') a.setToolTip(menu_a.toolTip()) self._wand_actions['color_select'] = menu_a = tool_menu.addAction( QIcon(get_icon('color_select.png')), 'color wand', self.set_color_wand_mode) menu_a.setToolTip('Select colors') self._wand_actions['row_select'] = menu_a = tool_menu.addAction( QIcon(get_icon('row_select.png')), 'row selection', self.set_row_wand_mode) menu_a.setToolTip('Select pixel rows') self._wand_actions['col_select'] = menu_a = tool_menu.addAction( QIcon(get_icon('col_select.png')), 'column selection', self.set_col_wand_mode) menu_a.setToolTip('Select pixel columns') a.setMenu(tool_menu) # color_wand widgets self.distance_slider = slider = QSlider(Qt.Horizontal) slider.setMinimum(0) slider.setMaximum(255) slider.setValue(30) slider.setSingleStep(1) self.lbl_slider = QLabel('30') slider.valueChanged.connect(lambda i: self.lbl_slider.setText(str(i))) slider.setMaximumWidth(self.combo.sizeHint().width()) self.cb_whole_fig = QCheckBox('Whole plot') self.cb_whole_fig.setToolTip('Select the colors on the entire plot') self.cb_use_alpha = QCheckBox('Use alpha') self.cb_use_alpha.setToolTip('Use the alpha channel, i.e. the ' 'transparency of the RGBA image.') self.color_wand_actions = [ self.addWidget(slider), self.addWidget(self.lbl_slider), self.addWidget(self.cb_whole_fig), self.addWidget(self.cb_use_alpha)] self.set_label_wand_mode() self.addSeparator() type_group = QActionGroup(self) self._type_actions = {} # new selection action self._type_actions['new_select'] = a = self.addAction( QIcon(get_icon('new_selection.png')), 'Create a new selection') a.setToolTip('Select pixels within a rectangle and ignore the current ' 'selection') a.setCheckable(True) type_group.addAction(a) # add to selection action self._type_actions['add_select'] = a = self.addAction( QIcon(get_icon('add_select.png')), 'Add to selection') a.setToolTip('Select pixels within a rectangle and add them to the ' 'current selection') a.setCheckable(True) type_group.addAction(a) # remove action self._type_actions['remove_select'] = a = self.addAction( QIcon(get_icon('remove_select.png')), 'Remove from selection') a.setToolTip('Select pixels within a rectangle and remove them from ' 'the current selection') a.setCheckable(True) type_group.addAction(a) # info button self.addSeparator() self.info_button = InfoButton(self, 'selection_toolbar.rst') self.addWidget(self.info_button) # selection appearence options self.addSeparator() self.sl_alpha = slider = QSlider(Qt.Horizontal) self._appearance_actions['alpha'] = self.addWidget(slider) slider.setMinimum(0) slider.setMaximum(100) slider.setValue(100) slider.setSingleStep(1) self.lbl_alpha_slider = QLabel('100 %') slider.valueChanged.connect( lambda i: self.lbl_alpha_slider.setText(str(i) + ' %')) slider.valueChanged.connect(self.update_alpha) slider.setMaximumWidth(self.combo.sizeHint().width()) # Select all and invert selection buttons self.addSeparator() self._actions['select_all'] = a = self.addAction( QIcon(get_icon('select_all.png')), 'all', self.select_all) a.setToolTip('Select all labels') self._actions['expand_select'] = a = self.addAction( QIcon(get_icon('expand_select.png')), 'expand', self.expand_selection) a.setToolTip('Expand the selected areas to select the entire feature') self._actions['invert_select'] = a = self.addAction( QIcon(get_icon('invert_select.png')), 'invert', self.invert_selection) a.setToolTip('Invert selection') self._actions['clear_select'] = a = self.addAction( QIcon(get_icon('clear_select.png')), 'clear', self.clear_selection) a.setToolTip('Clear selection') self._actions['select_right'] = a = self.addAction( QIcon(get_icon('select_right.png')), 'right', self.select_everything_to_the_right) a.setToolTip('Select everything to the right of each column') self._actions['select_pattern'] = a = self.addAction( QIcon(get_icon('pattern.png')), 'pattern', self.start_pattern_selection) a.setCheckable(True) a.setToolTip( 'Select a binary pattern/hatch within the current selection') # wand menu pattern_menu = QMenu(self) self._pattern_actions['binary'] = menu_a = pattern_menu.addAction( QIcon(get_icon('pattern.png')), 'Binary', self.set_binary_pattern_mode) menu_a.setToolTip( 'Select a binary pattern/hatch within the current selection') a.setToolTip(menu_a.toolTip()) self._pattern_actions['grey'] = menu_a = pattern_menu.addAction( QIcon(get_icon('pattern_grey.png')), 'Greyscale', self.set_grey_pattern_mode) menu_a.setToolTip( 'Select a pattern/hatch within the current selection based on ' 'grey scale colors') a.setMenu(pattern_menu) self.new_select_action.setChecked(True) for a in self._type_actions.values(): a.toggled.connect(self.add_or_remove_pattern) self.refresh()
def __init__(self, *args, **kwargs): from straditize.widgets.menu_actions import StraditizerMenuActions from straditize.widgets.progress_widget import ProgressWidget from straditize.widgets.data import DigitizingControl from straditize.widgets.selection_toolbar import SelectionToolbar from straditize.widgets.marker_control import MarkerControl from straditize.widgets.plots import PlotControl from straditize.widgets.axes_translations import AxesTranslations from straditize.widgets.image_correction import (ImageRotator, ImageRescaler) from straditize.widgets.colnames import ColumnNamesManager self._straditizers = [] super(StraditizerWidgets, self).__init__(*args, **kwargs) self.tree = QTreeWidget(parent=self) self.tree.setSelectionMode(QTreeWidget.NoSelection) self.refresh_button = QToolButton(self) self.refresh_button.setIcon(QIcon(get_psy_icon('refresh.png'))) self.refresh_button.setToolTip('Refresh from the straditizer') self.apply_button = EnableButton('Apply', parent=self) self.cancel_button = EnableButton('Cancel', parent=self) self.attrs_button = QPushButton('Attributes', parent=self) self.tutorial_button = QPushButton('Tutorial', parent=self) self.tutorial_button.setCheckable(True) self.error_msg = PyErrorMessage(self) self.stradi_combo = QComboBox() self.btn_open_stradi = QToolButton() self.btn_open_stradi.setIcon(QIcon(get_psy_icon('run_arrow.png'))) self.btn_close_stradi = QToolButton() self.btn_close_stradi.setIcon(QIcon(get_psy_icon('invalid.png'))) self.btn_reload_autosaved = QPushButton("Reload") self.btn_reload_autosaved.setToolTip( "Close the straditizer and reload the last autosaved project") # --------------------------------------------------------------------- # --------------------------- Tree widgets ---------------------------- # --------------------------------------------------------------------- self.tree.setHeaderLabels(['', '']) self.tree.setColumnCount(2) self.progress_item = QTreeWidgetItem(0) self.progress_item.setText(0, 'ToDo list') self.progress_widget = ProgressWidget(self, self.progress_item) self.menu_actions_item = QTreeWidgetItem(0) self.menu_actions_item.setText(0, 'Images import/export') self.tree.addTopLevelItem(self.menu_actions_item) self.menu_actions = StraditizerMenuActions(self) self.digitizer_item = item = QTreeWidgetItem(0) item.setText(0, 'Digitization control') self.digitizer = DigitizingControl(self, item) self.col_names_item = item = QTreeWidgetItem(0) item.setText(0, 'Column names') self.colnames_manager = ColumnNamesManager(self, item) self.add_info_button(item, 'column_names.rst') self.axes_translations_item = item = QTreeWidgetItem(0) item.setText(0, 'Axes translations') self.axes_translations = AxesTranslations(self, item) self.image_transform_item = item = QTreeWidgetItem(0) item.setText(0, 'Transform source image') self.image_rescaler = ImageRescaler(self, item) self.image_rotator_item = item = QTreeWidgetItem(0) item.setText(0, 'Rotate image') self.image_rotator = ImageRotator(self) self.image_transform_item.addChild(item) self.image_rotator.setup_children(item) self.plot_control_item = item = QTreeWidgetItem(0) item.setText(0, 'Plot control') self.plot_control = PlotControl(self, item) self.add_info_button(item, 'plot_control.rst') self.marker_control_item = item = QTreeWidgetItem(0) item.setText(0, 'Marker control') self.marker_control = MarkerControl(self, item) self.add_info_button(item, 'marker_control.rst') # --------------------------------------------------------------------- # ----------------------------- Toolbars ------------------------------ # --------------------------------------------------------------------- self.selection_toolbar = SelectionToolbar(self, 'Selection toolbar') # --------------------------------------------------------------------- # ----------------------------- InfoButton ---------------------------- # --------------------------------------------------------------------- self.info_button = InfoButton(self, get_doc_file('straditize.rst')) # --------------------------------------------------------------------- # --------------------------- Layouts --------------------------------- # --------------------------------------------------------------------- stradi_box = QHBoxLayout() stradi_box.addWidget(self.stradi_combo, 1) stradi_box.addWidget(self.btn_open_stradi) stradi_box.addWidget(self.btn_close_stradi) attrs_box = QHBoxLayout() attrs_box.addWidget(self.attrs_button) attrs_box.addStretch(0) attrs_box.addWidget(self.tutorial_button) btn_box = QHBoxLayout() btn_box.addWidget(self.refresh_button) btn_box.addWidget(self.info_button) btn_box.addStretch(0) btn_box.addWidget(self.apply_button) btn_box.addWidget(self.cancel_button) reload_box = QHBoxLayout() reload_box.addWidget(self.btn_reload_autosaved) reload_box.addStretch(0) vbox = QVBoxLayout() vbox.addLayout(stradi_box) vbox.addWidget(self.tree) vbox.addLayout(attrs_box) vbox.addLayout(btn_box) vbox.addLayout(reload_box) self.setLayout(vbox) self.apply_button.setEnabled(False) self.cancel_button.setEnabled(False) self.tree.expandItem(self.progress_item) self.tree.expandItem(self.digitizer_item) # --------------------------------------------------------------------- # --------------------------- Connections ----------------------------- # --------------------------------------------------------------------- self.stradi_combo.currentIndexChanged.connect(self.set_current_stradi) self.refresh_button.clicked.connect(self.refresh) self.attrs_button.clicked.connect(self.edit_attrs) self.tutorial_button.clicked.connect(self.start_tutorial) self.open_external.connect(self._create_straditizer_from_args) self.btn_open_stradi.clicked.connect( self.menu_actions.open_straditizer) self.btn_close_stradi.clicked.connect(self.close_straditizer) self.btn_reload_autosaved.clicked.connect(self.reload_autosaved) self.refresh() header = self.tree.header() header.setStretchLastSection(False) header.setSectionResizeMode(0, QHeaderView.Stretch)
def icon(self): """The icon of this instance in the :class:`Preferences` dialog""" return QIcon(get_icon('rcParams.png'))
def set_poly_select_mode(self): """Set the current wand tool to the color wand""" self.select_type = 'poly' self.select_action.setIcon(QIcon(get_icon('poly_select.png'))) self._action_clicked = None self.toggle_selection()
def set_grey_pattern_mode(self): """Set the current pattern mode to the binary pattern""" self.pattern_type = 'grey' self.select_pattern_action.setIcon(QIcon(get_icon('pattern_grey.png')))
def __init__(self, *args, **kwargs): """ Parameters ---------- help_explorer: psyplot_gui.help_explorer.HelpExplorer The help explorer to show the documentation of one formatoption shell: IPython.core.interactiveshell.InteractiveShell The shell that can be used to update the current subproject via:: psy.gcp().update(**kwargs) where ``**kwargs`` is defined through the selected formatoption in the :attr:`fmt_combo` combobox and the value in the :attr:`line_edit` editor ``*args, **kwargs`` Any other keyword for the QWidget class """ help_explorer = kwargs.pop('help_explorer', None) shell = kwargs.pop('shell', None) super(FormatoptionWidget, self).__init__(*args, **kwargs) self.help_explorer = help_explorer self.shell = shell # --------------------------------------------------------------------- # -------------------------- Child widgets ---------------------------- # --------------------------------------------------------------------- self.group_combo = QComboBox(parent=self) self.fmt_combo = QComboBox(parent=self) self.line_edit = QLineEdit(parent=self) self.run_button = QToolButton(parent=self) self.keys_button = QPushButton('Formatoption keys', parent=self) self.summaries_button = QPushButton('Summaries', parent=self) self.docs_button = QPushButton('Docs', parent=self) self.grouped_cb = QCheckBox('grouped', parent=self) self.all_groups_cb = QCheckBox('all groups', parent=self) self.include_links_cb = QCheckBox('include links', parent=self) # --------------------------------------------------------------------- # -------------------------- Descriptions ----------------------------- # --------------------------------------------------------------------- self.group_combo.setToolTip('Select the formatoption group') self.fmt_combo.setToolTip('Select the formatoption to update') self.line_edit.setToolTip( 'Insert the value which what you want to update the selected ' 'formatoption and hit right button. The code is executed in the ' 'main console.') self.run_button.setIcon(QIcon(get_icon('run_arrow.png'))) self.run_button.setToolTip('Update the selected formatoption') self.keys_button.setToolTip( 'Show the formatoption keys in this group (or in all ' 'groups) in the help explorer') self.summaries_button.setToolTip( 'Show the formatoption summaries in this group (or in all ' 'groups) in the help explorer') self.docs_button.setToolTip( 'Show the formatoption documentations in this group (or in all ' 'groups) in the help explorer') self.grouped_cb.setToolTip( 'Group the formatoptions before displaying them in the help ' 'explorer') self.all_groups_cb.setToolTip('Use all groups when displaying the ' 'keys, docs or summaries') self.include_links_cb.setToolTip( 'Include links to remote documentations when showing the ' 'keys, docs and summaries in the help explorer (requires ' 'intersphinx)') # --------------------------------------------------------------------- # -------------------------- Connections ------------------------------ # --------------------------------------------------------------------- self.group_combo.currentIndexChanged[int].connect(self.fill_fmt_combo) self.fmt_combo.currentIndexChanged[int].connect(self.show_fmt_info) self.run_button.clicked.connect(self.run_code) self.line_edit.returnPressed.connect(self.run_button.click) self.keys_button.clicked.connect( partial(self.show_all_fmt_info, 'keys')) self.summaries_button.clicked.connect( partial(self.show_all_fmt_info, 'summaries')) self.docs_button.clicked.connect( partial(self.show_all_fmt_info, 'docs')) # --------------------------------------------------------------------- # ------------------------------ Layouts ------------------------------ # --------------------------------------------------------------------- self.combos = QHBoxLayout() self.combos.addWidget(self.group_combo) self.combos.addWidget(self.fmt_combo) self.execs = QHBoxLayout() self.execs.addWidget(self.line_edit) self.execs.addWidget(self.run_button) self.info_box = QHBoxLayout() self.info_box.addStretch(0) for w in [ self.keys_button, self.summaries_button, self.docs_button, self.all_groups_cb, self.grouped_cb, self.include_links_cb ]: self.info_box.addWidget(w) self.vbox = QVBoxLayout() self.vbox.addLayout(self.combos) self.vbox.addLayout(self.execs) self.vbox.addLayout(self.info_box) self.setLayout(self.vbox) # fill with content self.fill_combos_from_project(psy.gcp()) psy.Project.oncpchange.connect(self.fill_combos_from_project)
def __init__(self, show=True): """ Parameters ---------- show: bool If True, the created mainwindow is show """ if sys.stdout is None: sys.stdout = StreamToLogger(self.logger) if sys.stderr is None: sys.stderr = StreamToLogger(self.logger) super(MainWindow, self).__init__() self.setWindowIcon(QIcon(get_icon('logo.png'))) #: list of figures from the psyplot backend self.figures = [] self.error_msg = PyErrorMessage(self) self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks | QMainWindow.AllowTabbedDocks) #: Inprocess console self.console = ConsoleWidget(self) self.project_actions = {} self.config_pages = [] self.open_file_options = OrderedDict([ ('new psyplot plot from dataset', self.open_external_files), ('new psyplot project', partial(self.open_external_files, [])), ]) # --------------------------------------------------------------------- # ----------------------------- Menus --------------------------------- # --------------------------------------------------------------------- # ######################## File menu ################################## # --------------------------- New plot -------------------------------- self.file_menu = QMenu('File', parent=self) self.new_plot_action = QAction('New plot', self) self.new_plot_action.setStatusTip( 'Use an existing dataset (or open a new one) to create one or ' 'more plots') self.register_shortcut(self.new_plot_action, QKeySequence.New) self.new_plot_action.triggered.connect(lambda: self.new_plots(True)) self.file_menu.addAction(self.new_plot_action) # --------------------------- Open project ---------------------------- self.open_project_menu = QMenu('Open project', self) self.file_menu.addMenu(self.open_project_menu) self.open_mp_action = QAction('New main project', self) self.register_shortcut(self.open_mp_action, QKeySequence.Open) self.open_mp_action.setStatusTip('Open a new main project') self.open_mp_action.triggered.connect(self.open_mp) self.open_project_menu.addAction(self.open_mp_action) self.open_sp_action = QAction('Add to current', self) self.register_shortcut( self.open_sp_action, QKeySequence('Ctrl+Shift+O', QKeySequence.NativeText)) self.open_sp_action.setStatusTip( 'Load a project as a sub project and add it to the current main ' 'project') self.open_sp_action.triggered.connect(self.open_sp) self.open_project_menu.addAction(self.open_sp_action) # ---------------------- load preset menu ----------------------------- self.load_preset_menu = QMenu('Load preset', parent=self) self.file_menu.addMenu(self.load_preset_menu) self.load_sp_preset_action = self.load_preset_menu.addAction( "For selection", self.load_sp_preset) self.load_sp_preset_action.setStatusTip( "Load a preset for the selected project") self.load_mp_preset_action = self.load_preset_menu.addAction( "For full project", self.load_mp_preset) self.load_sp_preset_action.setStatusTip( "Load a preset for the full project") # ----------------------- Save project -------------------------------- self.save_project_menu = QMenu('Save', parent=self) self.file_menu.addMenu(self.save_project_menu) self.save_mp_action = QAction('Full psyplot project', self) self.save_mp_action.setStatusTip( 'Save the entire project into a pickle file') self.register_shortcut(self.save_mp_action, QKeySequence.Save) self.save_mp_action.triggered.connect(self.save_mp) self.save_project_menu.addAction(self.save_mp_action) self.save_sp_action = QAction('Selected psyplot project', self) self.save_sp_action.setStatusTip( 'Save the selected sub project into a pickle file') self.save_sp_action.triggered.connect(self.save_sp) self.save_project_menu.addAction(self.save_sp_action) # ------------------------ Save project as ---------------------------- self.save_project_as_menu = QMenu('Save as', parent=self) self.file_menu.addMenu(self.save_project_as_menu) self.save_mp_as_action = QAction('Full psyplot project', self) self.save_mp_as_action.setStatusTip( 'Save the entire project into a pickle file') self.register_shortcut(self.save_mp_as_action, QKeySequence.SaveAs) self.save_mp_as_action.triggered.connect( partial(self.save_mp, new_fname=True)) self.save_project_as_menu.addAction(self.save_mp_as_action) self.save_sp_as_action = QAction('Selected psyplot project', self) self.save_sp_as_action.setStatusTip( 'Save the selected sub project into a pickle file') self.save_sp_as_action.triggered.connect( partial(self.save_sp, new_fname=True)) self.save_project_as_menu.addAction(self.save_sp_as_action) # ------------------------ Save preset -------------------------------- self.save_preset_menu = QMenu('Save preset', parent=self) self.file_menu.addMenu(self.save_preset_menu) self.save_sp_preset_action = self.save_preset_menu.addAction( "Selection", self.save_sp_preset) self.save_sp_preset_action.setStatusTip( "Save the formatoptions of the selected project as a preset") self.save_mp_preset_action = self.save_preset_menu.addAction( "Full project", self.save_mp_preset) self.save_sp_preset_action.setStatusTip( "Save the formatoptions of the full project as a preset") # -------------------------- Pack project ----------------------------- self.pack_project_menu = QMenu('Zip project files', parent=self) self.file_menu.addMenu(self.pack_project_menu) self.pack_mp_action = QAction('Full psyplot project', self) self.pack_mp_action.setStatusTip( 'Pack all the data of the main project into one folder') self.pack_mp_action.triggered.connect(partial(self.save_mp, pack=True)) self.pack_project_menu.addAction(self.pack_mp_action) self.pack_sp_action = QAction('Selected psyplot project', self) self.pack_sp_action.setStatusTip( 'Pack all the data of the current sub project into one folder') self.pack_sp_action.triggered.connect(partial(self.save_sp, pack=True)) self.pack_project_menu.addAction(self.pack_sp_action) # ------------------------ Export figures ----------------------------- self.export_project_menu = QMenu('Export figures', parent=self) self.file_menu.addMenu(self.export_project_menu) self.export_mp_action = QAction('Full psyplot project', self) self.export_mp_action.setStatusTip( 'Pack all the data of the main project into one folder') self.export_mp_action.triggered.connect(self.export_mp) self.register_shortcut(self.export_mp_action, QKeySequence('Ctrl+E', QKeySequence.NativeText)) self.export_project_menu.addAction(self.export_mp_action) self.export_sp_action = QAction('Selected psyplot project', self) self.export_sp_action.setStatusTip( 'Pack all the data of the current sub project into one folder') self.register_shortcut( self.export_sp_action, QKeySequence('Ctrl+Shift+E', QKeySequence.NativeText)) self.export_sp_action.triggered.connect(self.export_sp) self.export_project_menu.addAction(self.export_sp_action) # ------------------------ Close project ------------------------------ self.file_menu.addSeparator() self.close_project_menu = QMenu('Close project', parent=self) self.file_menu.addMenu(self.close_project_menu) self.close_mp_action = QAction('Full psyplot project', self) self.register_shortcut( self.close_mp_action, QKeySequence('Ctrl+Shift+W', QKeySequence.NativeText)) self.close_mp_action.setStatusTip( 'Close the main project and delete all data and plots out of ' 'memory') self.close_mp_action.triggered.connect( lambda: psy.close(psy.gcp(True).num)) self.close_project_menu.addAction(self.close_mp_action) self.close_sp_action = QAction('Selected psyplot project', self) self.close_sp_action.setStatusTip( 'Close the selected arrays project and delete all data and plots ' 'out of memory') self.register_shortcut(self.close_sp_action, QKeySequence.Close) self.close_sp_action.triggered.connect( lambda: psy.gcp().close(True, True)) self.close_project_menu.addAction(self.close_sp_action) # ----------------------------- Quit ---------------------------------- if sys.platform != 'darwin': # mac os makes this anyway self.quit_action = QAction('Quit', self) self.quit_action.triggered.connect(self.close) self.quit_action.triggered.connect( QtCore.QCoreApplication.instance().quit) self.register_shortcut(self.quit_action, QKeySequence.Quit) self.file_menu.addAction(self.quit_action) self.menuBar().addMenu(self.file_menu) # ######################## Console menu ############################### self.console_menu = QMenu('Console', self) self.console_menu.addActions(self.console.actions()) self.menuBar().addMenu(self.console_menu) # ######################## Windows menu ############################### self.windows_menu = QMenu('Windows', self) self.menuBar().addMenu(self.windows_menu) # ############################ Help menu ############################## self.help_menu = QMenu('Help', parent=self) self.menuBar().addMenu(self.help_menu) # -------------------------- Preferences ------------------------------ self.help_action = QAction('Preferences', self) self.help_action.triggered.connect(lambda: self.edit_preferences(True)) self.register_shortcut(self.help_action, QKeySequence.Preferences) self.help_menu.addAction(self.help_action) # ---------------------------- About ---------------------------------- self.about_action = QAction('About', self) self.about_action.triggered.connect(self.about) self.help_menu.addAction(self.about_action) # ---------------------------- Dependencies --------------------------- self.dependencies_action = QAction('Dependencies', self) self.dependencies_action.triggered.connect( lambda: self.show_dependencies(True)) self.help_menu.addAction(self.dependencies_action) self.dockwidgets = [] # --------------------------------------------------------------------- # -------------------------- Dock windows ----------------------------- # --------------------------------------------------------------------- #: tab widget displaying the arrays in current main and sub project #: tree widget displaying the open datasets self.project_content = ProjectContentWidget(parent=self) self.ds_tree = DatasetTree(parent=self) #: tree widget displaying the open figures self.figures_tree = FiguresTree(parent=self) #: help explorer self.help_explorer = help_explorer = HelpExplorer(parent=self) if 'HTML help' in help_explorer.viewers and help_explorer.viewers[ 'HTML help'].sphinx_thread is not None: help_explorer.viewers[ 'HTML help'].sphinx_thread.html_ready.connect( self.focus_on_console) #: the DataFrameEditor widgets self.dataframeeditors = [] #: general formatoptions widget self.fmt_widget = FormatoptionWidget(parent=self, help_explorer=help_explorer, console=self.console) # load plugin widgets self.plugins = plugins = OrderedDict([ ('console', self.console), ('project_content', self.project_content), ('ds_tree', self.ds_tree), ('figures_tree', self.figures_tree), ('help_explorer', self.help_explorer), ('fmt_widget', self.fmt_widget), ]) self.default_plugins = list(plugins) for plugin_name, w_class in six.iteritems(rcParams.load_plugins()): plugins[plugin_name] = w_class(parent=self) self.add_mp_to_menu() psy.Project.oncpchange.connect(self.eventually_add_mp_to_menu) self.windows_menu.addSeparator() self.window_layouts_menu = QMenu('Window layouts', self) self.restore_layout_action = QAction('Restore default layout', self) self.restore_layout_action.triggered.connect(self.setup_default_layout) self.window_layouts_menu.addAction(self.restore_layout_action) self.windows_menu.addMenu(self.window_layouts_menu) self.panes_menu = QMenu('Panes', self) self.windows_menu.addMenu(self.panes_menu) self.dataframe_menu = QMenu('DataFrame editors', self) self.dataframe_menu.addAction( 'New Editor', partial(self.new_data_frame_editor, None, 'DataFrame Editor')) self.dataframe_menu.addSeparator() self.windows_menu.addMenu(self.dataframe_menu) self.central_widgets_menu = menu = QMenu('Central widget', self) self.windows_menu.addMenu(menu) self.central_widgets_actions = group = QActionGroup(self) group.setExclusive(True) # --------------------------------------------------------------------- # -------------------------- connections ------------------------------ # --------------------------------------------------------------------- self.console.help_explorer = help_explorer psyp.default_print_func = partial(help_explorer.show_rst, oname='formatoption_docs') psy.PlotterInterface._print_func = psyp.default_print_func self.setCentralWidget(self.console) # make sure that the plots are shown between the project content and # the help explorer widget self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea) # make sure that the formatoption widgets are shown between the # project content and the help explorer widget self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea) # --------------------------------------------------------------------- # ------------------------------ closure ------------------------------ # --------------------------------------------------------------------- if show: self.help_explorer.show_intro(self.console.intro_msg) # --------------------------------------------------------------------- # ------------------------- open_files_server ------------------------- # --------------------------------------------------------------------- self.callbacks = { 'new_plot': self.open_external.emit, 'change_cwd': self._change_cwd, 'run_script': self.console.run_script.emit, 'command': self.console.run_command.emit, } # Server to open external files on a single instance self.open_files_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) if rcParams['main.listen_to_port']: self._file_thread = Thread(target=self.start_open_files_server) self._file_thread.setDaemon(True) self._file_thread.start() self.open_external.connect(self._open_external_files) self.config_pages.extend([GuiRcParamsWidget, PsyRcParamsWidget]) # display the statusBar statusbar = self.statusBar() self.figures_label = QLabel() statusbar.addWidget(self.figures_label) self.plugin_label = QLabel() statusbar.addWidget(self.plugin_label) self.default_widths = {} self.setup_default_layout() if show: self.showMaximized() # save the default widths after they have been shown for w in self.plugins.values(): if w.dock is not None: self.default_widths[w] = w.dock.size().width() # hide plugin widgets that should be hidden at startup. Although this # has been executed by :meth:`setup_default_layout`, we have to execute # it again after the call of showMaximized for name, w in self.plugins.items(): if name != self.central_widget_key: w.to_dock(self) if w.hidden: w.hide_plugin() else: w.create_central_widget_action(self).setChecked(True) self._is_open = True
def add_item(self, what, get_artists, plot_func=None, remove_func=None, can_be_plotted=None): """Add a plot object to the table Parameters ---------- what: str The description of the plot object get_artists: function A function that takes no arguments and returns the artists plot_func: function, optional A function that takes no arguments and makes the plot. remove_func: function, optional A function that takes no arguments and removes the plot. can_be_plotted: function, optional A function that takes no argument and returns True if the plot can be made. """ def hide_or_show(checked): checked = checked is True or checked == Qt.Checked artist = None for artist in get_artists(): artist.set_visible(checked) if artist is not None: self.draw_figs(get_artists()) def trigger_plot_btn(): a = next(iter(get_artists()), None) if a is None: if can_be_plotted is None or can_be_plotted(): plot_func() cb.setChecked(True) btn.setIcon(QIcon(get_icon('invalid.png'))) btn.setToolTip('Remove ' + what) self.draw_figs(get_artists()) cb.setEnabled(True) else: fig = a.axes.figure figs = {a.axes.figure for a in get_artists()} remove_func() btn.setIcon(QIcon(get_icon('valid.png'))) btn.setToolTip('Show ' + what) for fig in figs: fig.canvas.draw_idle() cb.setEnabled(False) self.get_artists_funcs[what] = get_artists a = next(iter(get_artists()), None) cb = QCheckBox() cb.label = what self.hide_funcs[what] = hide_or_show cb.setChecked( Qt.Checked if a is not None and a.get_visible() else Qt.Unchecked) cb.stateChanged.connect(hide_or_show) row = self.rowCount() self.setRowCount(row + 1) self.setVerticalHeaderLabels(list(self.get_artists_funcs)) self.setCellWidget(row, 0, cb) if plot_func is not None: btn = QToolButton() btn.setIcon( QIcon(get_icon(('in' if a is None else '') + 'valid.png'))) btn.clicked.connect(trigger_plot_btn) btn.setEnabled(can_be_plotted is None or can_be_plotted()) btn.setToolTip(('Remove ' if a else 'Show ') + what) self.can_be_plotted_funcs[what] = can_be_plotted btn.label = what self.setCellWidget(row, 1, btn)
def __init__(self, *args, **kwargs): super(DataFrameEditor, self).__init__(*args, **kwargs) self.error_msg = PyErrorMessage(self) # Label for displaying the DataFrame size self.lbl_size = QLabel() # A Checkbox for enabling and disabling the editability of the index self.cb_index_editable = QCheckBox('Index editable') # A checkbox for enabling and disabling the change of data types self.cb_dtypes_changeable = QCheckBox('Datatypes changeable') # A checkbox for enabling and disabling sorting self.cb_enable_sort = QCheckBox('Enable sorting') # A button to open a dataframe from the file self.btn_open_df = QToolButton(parent=self) self.btn_open_df.setIcon(QIcon(get_icon('run_arrow.png'))) self.btn_open_df.setToolTip('Open a DataFrame from your disk') self.btn_from_console = LoadFromConsoleButton(pd.DataFrame) self.btn_from_console.setToolTip('Show a DataFrame from the console') # The table to display the DataFrame self.table = DataFrameView(pd.DataFrame(), self) # format line edit self.format_editor = QLineEdit() self.format_editor.setText(self.table.model()._format) # format update button self.btn_change_format = QPushButton('Update') self.btn_change_format.setEnabled(False) # table clearing button self.btn_clear = QPushButton('Clear') self.btn_clear.setToolTip( 'Clear the table and disconnect from the DataFrame') # refresh button self.btn_refresh = QToolButton() self.btn_refresh.setIcon(QIcon(get_icon('refresh.png'))) self.btn_refresh.setToolTip('Refresh the table') # close button self.btn_close = QPushButton('Close') self.btn_close.setToolTip('Close this widget permanentely') # --------------------------------------------------------------------- # ------------------------ layout -------------------------------- # --------------------------------------------------------------------- vbox = QVBoxLayout() self.top_hbox = hbox = QHBoxLayout() hbox.addWidget(self.cb_index_editable) hbox.addWidget(self.cb_dtypes_changeable) hbox.addWidget(self.cb_enable_sort) hbox.addWidget(self.lbl_size) hbox.addStretch(0) hbox.addWidget(self.btn_open_df) hbox.addWidget(self.btn_from_console) vbox.addLayout(hbox) vbox.addWidget(self.table) self.bottom_hbox = hbox = QHBoxLayout() hbox.addWidget(self.format_editor) hbox.addWidget(self.btn_change_format) hbox.addStretch(0) hbox.addWidget(self.btn_clear) hbox.addWidget(self.btn_close) hbox.addWidget(self.btn_refresh) vbox.addLayout(hbox) self.setLayout(vbox) # --------------------------------------------------------------------- # ------------------------ Connections -------------------------------- # --------------------------------------------------------------------- self.cb_dtypes_changeable.stateChanged.connect( self.set_dtypes_changeable) self.cb_index_editable.stateChanged.connect(self.set_index_editable) self.btn_from_console.object_loaded.connect(self._open_ds_from_console) self.rows_inserted.connect(lambda i, n: self.set_lbl_size_text()) self.format_editor.textChanged.connect(self.toggle_fmt_button) self.btn_change_format.clicked.connect(self.update_format) self.btn_clear.clicked.connect(self.clear_table) self.btn_close.clicked.connect(self.clear_table) self.btn_close.clicked.connect(lambda: self.close()) self.btn_refresh.clicked.connect(self.table.reset_model) self.btn_open_df.clicked.connect(self._open_dataframe) self.table.set_index_action.triggered.connect( self.update_index_editable) self.table.append_index_action.triggered.connect( self.update_index_editable) self.cb_enable_sort.stateChanged.connect( self.table.setSortingEnabled)