def init(self): # Check if this class has been initialized before, and do so if not if not self.init_flag: self.first_init() # Create a layout for this widget box_layout = GL.QHBoxLayout(self) box_layout.setContentsMargins(0, 0, 0, 0) # Create a combobox for cmaps cmaps_box = GW.EditableComboBox() validator = GW.ComboBoxValidator(cmaps_box) cmaps_box.setValidator(validator) # Add all colormaps to cmaps_box for cmap in self.cmaps_cl: cmap_icon = self.cmap_icons[cmap] cmaps_box.addItem(cmap_icon, cmap) # Add some separators for i in reversed(self.cum_len[:-2]): cmaps_box.insertSeparator(i) # Set remaining properties set_box_value(cmaps_box, rcParams['image.cmap']) cmaps_box.setIconSize(QC.QSize(*self.cmap_size)) cmaps_box.completer().popup().setIconSize(QC.QSize(*self.cmap_size)) get_modified_signal(cmaps_box, str).connect(self.cmap_selected) cmaps_box.focusLost.connect( lambda: set_box_value(cmaps_box, get_box_value(cmaps_box, int))) # Add cmaps_box to layout box_layout.addWidget(cmaps_box) self.cmaps_box = cmaps_box
def init(self): # Make layout for setting the value range of the histogram hist_range_layout = GL.QHBoxLayout(self) hist_range_layout.setContentsMargins(0, 0, 0, 0) # Make a box for setting the value range of the histogram # TODO: Maybe use dual lineedits instead to eliminate range problem? hist_range_box = GW.DualSpinBox((float, float), r"<html>≤ X ≤</html>") x_min_box, x_max_box = hist_range_box[:] x_min_box.setRange(-9999999, 9999999) x_min_box.setToolTip("Minimum value to be included in the histogram") x_max_box.setRange(-9999999, 9999999) x_max_box.setToolTip("Maximum value to be included in the histogram") set_box_value(hist_range_box, (0, 0)) hist_range_box.setEnabled(False) self.range_box = hist_range_box # Make a checkbox for enabling/disabling the use of this range hist_range_flag = GW.QCheckBox() hist_range_flag.setToolTip("Toggle the use of a manual histogram value" " range") set_box_value(hist_range_flag, False) self.range_flag = hist_range_flag # Connect signals for hist_range_flag get_modified_signal(hist_range_flag).connect(hist_range_box.setEnabled) # Add everything together hist_range_layout.addWidget(hist_range_flag) hist_range_layout.addWidget(hist_range_box)
def init(self, widget, text, tooltip): """ Sets up the togglebox after it has been initialized. """ # Create the box_layout box_layout = GL.QHBoxLayout(self) box_layout.setContentsMargins(0, 0, 0, 0) # Create a checkbox for toggling the widget if text is not None: checkbox = GW.QCheckBox(text) else: checkbox = GW.QCheckBox() box_layout.addWidget(checkbox) self.checkbox = checkbox self.left_box = checkbox # Set tooltip if tooltip is not None: checkbox.setToolTip(tooltip) # Add the widget to it box_layout.addWidget(widget) self.widget = widget self.right_box = widget # Connect some signals get_modified_signal(checkbox).connect(widget.setEnabled) # Make sure that the checkbox is unchecked set_box_value(checkbox, False) widget.setEnabled(False)
def multi_data_box(self): """ Creates a widget box for setting the data for multiple 'DataND' props and returns it. """ # Make a tab widget for holding data tabs tab_widget = MultiDataTabWidget() self.tab_widget = tab_widget # Create add button for tabs add_but = GW.QToolButton() add_but.setToolTip("Add additional data set") tab_widget.setCornerWidget(add_but, QC.Qt.TopRightCorner) # If this theme has an 'add' icon, use it if QG.QIcon.hasThemeIcon('add'): add_but.setIcon(QG.QIcon.fromTheme('add')) # Else, use a simple plus else: add_but.setText('+') # Connect tab widget signals get_modified_signal(add_but).connect(self.add_data_box) tab_widget.tabCloseRequested.connect(self.remove_data_box) # Add initial data box self.add_data_box() # Return box return (tab_widget, )
def add_data_box(self): """ Adds a new data tab to this plot property. """ # Create a default widget for the new DataND prop data_prop = GW.BaseBox() get_modified_signal(data_prop).connect(self.tab_widget.modified) # Create a dictionary with all requirements of this property prop_kwargs = { req: getattr(self, req) for req in self.data_prop.REQUIREMENTS } # Create the DataND prop prop_layout = self.data_prop(**prop_kwargs) # Set prop_layout as the layout for data_prop data_prop.setLayout(prop_layout) # Obtain the name of this data_prop name = "data_%i" % (self.tab_widget.count()) # Add data_prop to the tab widget index = self.tab_widget.addTab(data_prop, name) # Switch focus to the new tab set_box_value(self.tab_widget, index) # Check if there is now more than a single tab self.tab_widget.setTabsClosable(self.tab_widget.count() > 1)
def add_entry(self): """ Adds a new entry to the entries box. """ # Create a combobox with the name of the entry name_box = self.get_entry_name_box() name_box.setToolTip("Select or type name for this entry") name_box.addItems(self.entry_types.keys()) set_box_value(name_box, -1) get_modified_signal(name_box).connect( lambda: self.create_value_box(name_box)) # Create a 'Delete'-button del_but = GW.QToolButton() del_but.setFixedSize(self.entry_height, self.entry_height) del_but.setToolTip("Delete this entry") get_modified_signal(del_but).connect( lambda: self.remove_entry(name_box)) # If this theme has a 'remove' icon, use it if QG.QIcon.hasThemeIcon('remove'): del_but.setIcon(QG.QIcon.fromTheme('remove')) # Else, use a standard icon else: del_but.setIcon(del_but.style().standardIcon( QW.QStyle.SP_DialogCloseButton)) # Add a new row to the grid layout next_row = self.entries_grid.getItemPosition( self.entries_grid.count() - 1)[0] + 1 self.entries_grid.addWidget(del_but, next_row, 0) self.entries_grid.addWidget(name_box, next_row, 1) self.entries_grid.addWidget(GW.QLabel(), next_row, 2)
def init(self, *args, **kwargs): # Call super setup super().init(*args, **kwargs) # Extract the two created comboboxes tables_box, columns_box = self[:] self.tables_box = tables_box self.columns_box = columns_box # Add items to data tables combobox for i, name in enumerate(self.tab_widget.tabNames()): tables_box.addItem(name) self.set_tables_box_item_tooltip(i, name) # Connect signals for tables_box self.tab_widget.tabTextChanged.connect(tables_box.setItemText) self.tab_widget.tabTextChanged.connect( self.set_tables_box_item_tooltip) self.tab_widget.tabWasInserted[int, str].connect(tables_box.insertItem) self.tab_widget.tabWasInserted[int, str].connect( self.set_tables_box_item_tooltip) self.tab_widget.tabWasRemoved.connect(tables_box.removeItem) get_modified_signal(tables_box, int).connect(self.set_columns_box_table) # Set initial contents of columns_box self.data_table = None self.model = None self.set_box_value((None, None))
def init(self): """ Sets up the entries box after it has been initialized. """ # Set the height of a single entry self.entry_height = 24 # Create empty dict of non-generic entry types self.entry_types = {} # Create empty dict of entry defaults self.entry_defaults = {} # Create empty set of banned entry names self.banned_names = sset() # Create the box_layout box_layout = GL.QVBoxLayout(self) box_layout.setContentsMargins(0, 0, 0, 0) # Create the entries_grid entries_grid = GL.QGridLayout() entries_grid.setContentsMargins(0, 0, 0, 0) entries_grid.setColumnStretch(1, 1) entries_grid.setColumnStretch(2, 2) box_layout.addLayout(entries_grid) self.entries_grid = entries_grid # Add a header entries_grid.addWidget(GW.QLabel(""), 0, 0) entries_grid.addWidget(GW.QLabel("Entry name"), 0, 1) entries_grid.addWidget(GW.QLabel("Entry value"), 0, 2) # Add an 'Add'-button add_but = GW.QToolButton() add_but.setFixedSize(self.entry_height, self.entry_height) add_but.setToolTip("Add new entry") get_modified_signal(add_but).connect(self.add_entry) box_layout.addWidget(add_but) # If this theme has an 'add' icon, use it if QG.QIcon.hasThemeIcon('add'): add_but.setIcon(QG.QIcon.fromTheme('add')) # Else, use a simple plus else: add_but.setText('+') # Set size policy self.setSizePolicy(QW.QSizePolicy.Preferred, QW.QSizePolicy.Fixed) # Set a minimum width for the first column self.entries_grid.setColumnMinimumWidth(0, self.entry_height)
def add_options_entry(self, widget): """ Adds the provided `widget` as an options entry to this options dialog. This allows for the values of `widget` to be tracked and potentially discarded/reverted. """ # Add widget as an entry to options_dict self.options_dict[widget] = get_box_value(widget) get_modified_signal(widget).connect(self.enable_apply_button)
def add_config_entry(self, name, widget, restart_flag=False): """ Adds the provided `widget` as a config entry to this config page with given `name`. This allows for the values of `widget` to be tracked and potentially discarded/reverted. """ # Make sure that name is lowercase name = name # Add widget as an entry to config_entries self.config_entries[name] = widget get_modified_signal(widget).connect(self.modified) # If restart_flag is True, connect set_restart_flag as well if restart_flag: get_modified_signal(widget).connect(self.set_restart_flag)
def init(self): # Install event filter to catch events that should close the popup self.installEventFilter(self) # Set dialog flags self.setWindowFlags(QC.Qt.Popup | QC.Qt.FramelessWindowHint) # Create a form layout layout = GL.QFormLayout(self) # Add a label stating the base name of the column self.base_name_label = GW.QLabel("") self.base_name_label.setAlignment(QC.Qt.AlignCenter) layout.addRow(self.base_name_label) # Create a n_val label n_val_box = GW.QLabel() n_val_box.setToolTip("Number of values in this column") # Add it to the layout layout.addRow("# of values", n_val_box) self.n_val_box = n_val_box # Create a name line-edit name_box = GW.QLineEdit() name_box.setToolTip("Set a custom name for this column or leave empty " "to use its default name") get_modified_signal(name_box).connect(self.column_name_changed) # Add it to the layout layout.addRow("Name", name_box) self.name_box = name_box # Create a dtype combobox dtype_box = GW.QComboBox() dtype_box.setToolTip("Set the data type for this column") dtype_box.addItems(self.model.dtypes.values()) dtype_box.popup_hidden.connect(lambda: name_box.setFocus(True)) # Add it to the layout layout.addRow("Data type", dtype_box) self.dtype_box = dtype_box
def init(self, item_type): """ Sets up the items box after it has been initialized. """ # Obtain the item_box if item_type is None: self.item_box = GW.LongGenericBox else: self.item_box = GW.type_box_dict.get(item_type, item_type) # Set the height of a single item self.entry_height = 24 # Create the box_layout box_layout = GL.QVBoxLayout(self) box_layout.setContentsMargins(0, 0, 0, 0) # Create the items_layout items_layout = GL.QVBoxLayout() items_layout.setContentsMargins(0, 0, 0, 0) box_layout.addLayout(items_layout) self.items_layout = items_layout # Add an 'Add'-button add_but = GW.QToolButton() add_but.setFixedSize(self.entry_height, self.entry_height) add_but.setToolTip("Add new item") get_modified_signal(add_but).connect(self.add_item) box_layout.addWidget(add_but) # If this theme has an 'add' icon, use it if QG.QIcon.hasThemeIcon('add'): add_but.setIcon(QG.QIcon.fromTheme('add')) # Else, use a simple plus else: add_but.setText('+') # Set size policy self.setSizePolicy(QW.QSizePolicy.Preferred, QW.QSizePolicy.Fixed)
def create_plots_tab(self): # Create a tab tab = GW.BaseBox() get_modified_signal(tab).connect(self.enable_apply_button) # Create layout layout = GL.QFormLayout(tab) # PLOT # Create a plot picker layout plot_layout = GL.QHBoxLayout() layout.addRow(plot_layout) # Create a label plot_label = GW.QLabel("Plot") plot_label.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed) plot_layout.addWidget(plot_label) # Create a combobox for choosing an existing plot plot_entries = GW.QComboBox() plot_entries.setToolTip("Select the plot entry you wish to edit") plot_layout.addWidget(plot_entries) get_modified_signal(plot_entries).disconnect(tab.modified) self.plot_entries = plot_entries # Add a toolbutton for adding a new plot entry add_but = GW.QToolButton() add_but.setToolTip("Add new plot entry") get_modified_signal(add_but).connect(self.add_entry) plot_layout.addWidget(add_but) # If this theme has an 'add' icon, use it if QG.QIcon.hasThemeIcon('add'): add_but.setIcon(QG.QIcon.fromTheme('add')) # Else, use a simple plus else: add_but.setText('+') # Add a separator layout.addSeparator() # Add a stacked widget here for dividing the plots plot_pages = GW.QStackedWidget() get_modified_signal(plot_entries, int).connect(plot_pages.setCurrentIndex) layout.addRow(plot_pages) self.plot_pages = plot_pages # Return tab return (tab, "Plots")
def add_entry(self): # Obtain index of this plot entry index = self.plot_entries.count() # Obtain name name = "%i_plot" % (index) # Create plot entry box plot_entry = FigurePlotEntry(index, name, self.figure_widget) # Connect signals plot_entry.entryNameChanged.connect( lambda x: self.plot_entries.setItemText(index, x)) plot_entry.entryRemoveRequested.connect(self.remove_entry) # Add it to the plot_entries and plot_pages self.plot_entries.addItem(name) self.plot_pages.addWidget(plot_entry) get_modified_signal(plot_entry).connect(self.enable_apply_button) # Set the shown entry to the new entry set_box_value(self.plot_entries, index)
def create_entry_layout(self): # Create layout layout = GL.QFormLayout(self) layout.setContentsMargins(0, 0, 0, 0) self.layout = layout # Create a name editor layout name_layout = GL.QHBoxLayout() layout.addRow('Name', name_layout) # Create entry name editor name_box = GW.QLineEdit() name_box.setToolTip("Name of this plot entry") set_box_value(name_box, self.name) get_modified_signal(name_box).connect(self.entryNameChanged) name_layout.addWidget(name_box) get_modified_signal(name_box).disconnect(self.modified) self.name_box = name_box # Add a toolbutton for deleting this plot entry del_but = GW.QToolButton() del_but.setToolTip("Delete this plot entry") get_modified_signal(del_but).connect(self.entryRemoveRequested) name_layout.addWidget(del_but) # If this theme has a 'remove' icon, use it if QG.QIcon.hasThemeIcon('remove'): del_but.setIcon(QG.QIcon.fromTheme('remove')) # Else, use a standard icon else: del_but.setIcon(del_but.style().standardIcon( QW.QStyle.SP_DialogCloseButton)) # Create a combobox for choosing a plot type plot_types = GW.QComboBox() plot_types.addItems(PLOT_TYPES['2D']) plot_types.setToolTip("Select the plot type you wish to use for this " "plot entry") set_box_value(plot_types, -1) get_modified_signal(plot_types).connect(self.set_plot_type) layout.addRow('Type', plot_types) self.plot_types = plot_types # Add a separator layout.addSeparator() # Create a dummy entry to start off self.plot_entry = GW.QWidget() layout.addRow(self.plot_entry)
def add_item(self): """ Adds a new item to the items box. """ # Create an item layout item_layout = GL.QHBoxLayout() item_layout.setContentsMargins(0, 0, 0, 0) # Create a generic box for this item item_box = self.item_box() item_box.setToolTip("Set value of this item") get_modified_signal(item_box).connect(self.modified) # Create a 'Delete'-button del_but = GW.QToolButton() del_but.setFixedSize(self.entry_height, self.entry_height) del_but.setToolTip("Delete this item") get_modified_signal(del_but).connect( lambda: self.remove_item(item_layout)) # If this theme has a 'remove' icon, use it if QG.QIcon.hasThemeIcon('remove'): del_but.setIcon(QG.QIcon.fromTheme('remove')) # Else, use a standard icon else: del_but.setIcon(del_but.style().standardIcon( QW.QStyle.SP_DialogCloseButton)) # Add a new row to the items layout item_layout.addWidget(del_but) item_layout.addWidget(item_box) self.items_layout.addLayout(item_layout) # Emit signal if item_box is not LongGenericBox if not isinstance(item_box, GW.LongGenericBox): self.modified.emit()
def init(self): """ Sets up the generic value box after it has been initialized. """ # Create the box_layout box_layout = GL.QHBoxLayout(self) box_layout.setContentsMargins(0, 0, 0, 0) self.box_layout = box_layout # Create a combobox for the type type_box = GW.QComboBox() type_box.addItems(sorted([x.__name__ for x in self.supported_types])) type_box.setSizePolicy(QW.QSizePolicy.Fixed, QW.QSizePolicy.Fixed) set_box_value(type_box, -1) get_modified_signal(type_box).connect(self.create_value_box) box_layout.addWidget(type_box) self.type_box = type_box # Create a default value box value_box = GW.QWidget() box_layout.addWidget(value_box) self.value_box = value_box
def add_config_page(self, config_page): """ Adds a provided `config_page` to this dialog, allowing it to be modified. The name of the config page determines where it will appear in the dialog. Parameters ---------- config_page : :obj:`~guipy.config.BaseConfigPage` object The config page object that must be added to this dialog. """ # Add a stretch to the layout of the page config_page.layout().addStretch() # Create scrollarea for the config page scroll_area = GW.QScrollArea(self) scroll_area.setWidgetResizable(True) scroll_area.setWidget(config_page) # Obtain the page sections of this config page main, sub, tab = self.get_page_sections(config_page.section_name) # Obtain the full page section for this config page page_section = self.config_pages.setdefault( main, sdict()).setdefault(sub, sdict()) # Check if this section existed before if(len(page_section) == 0): # Add the config page as a widget to the page_section and sections self.sections.addWidget(scroll_area) self.contents.addItem(main) # If this is the first section in contents, select it if(self.contents.count() == 1): self.contents.setCurrentRow(0) elif(len(page_section) == 1): # If so, a tab widget will be required tab_widget = GW.QTabWidget() page_section[''] = tab_widget # Obtain the index of the current widget at this section prev_page = page_section.values()[1] index = self.sections.indexOf(prev_page) # Remove this widget self.sections.removeWidget(prev_page) # Add the tab_widget self.sections.insertWidget(index, tab_widget) # Add the previous widget and the new config page to the tab_widget tab_widget.addTab(prev_page, page_section.keys()[1]) tab_widget.addTab(scroll_area, tab) else: # Obtain the current tab widget tab_widget = page_section[''] tab_widget.addTab(scroll_area, tab) # Connect signals get_modified_signal(config_page).connect(self.enable_apply_button) # Add this config page to the proper page section page_section[tab] = scroll_area
def init(self, import_func=None): # Create a layout layout = GL.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) # Create a dimensions layout dimensions_layout = GL.QHBoxLayout() layout.addLayout(dimensions_layout) # Add a label to this layout dimensions_layout.addWidget(GW.QLabel('Dimensions: ')) # Create dual spinbox for setting n_rows and n_cols dimensions_box = GW.DualSpinBox((int, int), "X") dimensions_layout.addWidget(dimensions_box) n_rows_box, n_cols_box = dimensions_box[:] n_rows_box.setRange(0, 9999999) n_rows_box.setToolTip("Number of rows in this data table (max. %i)" % (n_rows_box.maximum())) n_cols_box.setRange(0, 702) n_cols_box.setToolTip( "Number of columns in this data table (max. %i)" % (n_cols_box.maximum())) self.dimensions_box = dimensions_box # Create a layout for applying or reverting the dimensions buttons_layout = GL.QHBoxLayout() buttons_layout.setContentsMargins(0, 0, 0, 0) buttons_layout.setSpacing(0) dimensions_layout.addLayout(buttons_layout) # If this theme has a 'cancel' icon, use it if QG.QIcon.hasThemeIcon('cancel'): rev_icon = QG.QIcon.fromTheme('cancel') # Else, use a standard icon else: rev_icon = self.style().standardIcon( QW.QStyle.SP_DialogCancelButton) # Create a revert toolbutton rev_but = GW.QToolButton() rev_but.setToolTip("Revert to current data table dimensions") rev_but.setIcon(rev_icon) get_modified_signal(rev_but).connect(self.revert_table_dimensions) buttons_layout.addWidget(rev_but) # If this theme has an 'apply' icon, use it if QG.QIcon.hasThemeIcon('apply'): app_icon = QG.QIcon.fromTheme('apply') # Else, use a standard icon else: app_icon = self.style().standardIcon( QW.QStyle.SP_DialogApplyButton) # Create an apply toolbutton app_but = GW.QToolButton() app_but.setToolTip("Apply new data table dimensions") app_but.setIcon(app_icon) get_modified_signal(app_but).connect(self.apply_table_dimensions) buttons_layout.addWidget(app_but) # Add a stretcher dimensions_layout.addStretch() # Create the DataTableView object self.view = DataTableView(self, import_func) # Set initial values of the spinboxes self.revert_table_dimensions() # Connect signals from data table view self.view.model().rowCountChanged.connect( lambda x: set_box_value(n_rows_box, x)) self.view.model().columnCountChanged.connect( lambda x: set_box_value(n_cols_box, x)) self.view.model().lastColumnRemoved.connect( lambda: n_rows_box.setEnabled(False)) self.view.model().firstColumnInserted.connect( lambda: n_rows_box.setEnabled(True)) # Add data_table to the layout layout.addWidget(self.view)
def create_figure_tab(self): # Create a tab tab = GW.BaseBox() get_modified_signal(tab).connect(self.enable_apply_button) # Create layout layout = GL.QFormLayout(tab) # Make line edit for title title_box = GW.FigureLabelBox() title_box[0].setToolTip("Figure title") title_box[1].setToolTip("Title size") set_box_value(title_box, ('', { 'fontsize': rcParams['figure.titlesize'] })) self.add_options_entry(title_box) self.refreshing_figure.connect( lambda: self.axis.set_title(*get_box_value(title_box, str, dict))) layout.addRow("Title", title_box) self.title_box = title_box # X-AXIS # Create a group box for the X-axis x_axis_group = GW.QGroupBox("X-axis") layout.addRow(x_axis_group) x_axis_layout = GL.QFormLayout(x_axis_group) # Make a box for setting the label on the x-axis x_label_box = GW.FigureLabelBox() x_label_box[0].setToolTip("Label of the X-axis") x_label_box[1].setToolTip("Label size") set_box_value(x_label_box, ('', { 'fontsize': rcParams['axes.labelsize'] })) self.add_options_entry(x_label_box) self.refreshing_figure.connect(lambda: self.axis.set_xlabel( *get_box_value(x_label_box, str, dict))) x_axis_layout.addRow("Label", x_label_box) self.x_label_box = x_label_box # Make a box for setting the range on the x-axis # TODO: Allow for a small formula or cell range to be given instead? x_range_box = GW.DualLineEdit((float, float), r"<html>≤ X ≤</html>") x_min_box, x_max_box = x_range_box[:] x_min_box.setToolTip("Minimum value of the X-axis") x_max_box.setToolTip("Maximum value of the X-axis") set_box_value(x_range_box, self.axis.get_xlim()) # Connect signals for x_range_box self.refreshing_figure.connect( lambda: self.axis.set_xlim(*get_box_value(x_range_box), auto=None)) self.axis.callbacks.connect( 'xlim_changed', lambda x: set_box_value(x_range_box, x.get_xlim())) # Make togglebox for enabling/disabling the use of this range x_range_togglebox = GW.ToggleBox( x_range_box, tooltip="Check to manually set the X-axis range") self.add_options_entry(x_range_togglebox) x_axis_layout.addRow("Range", x_range_togglebox) # Connect signals for x_range_togglebox self.refreshing_figure.connect(lambda: self.axis.set_autoscalex_on( not get_box_value(x_range_togglebox, bool))) # Make a box for setting the scale on the x-axis x_scale_box = GW.QComboBox() x_scale_box.addItems(['linear', 'log', 'symlog', 'logit']) x_scale_box.setToolTip("Value scale of the X-axis") self.add_options_entry(x_scale_box) self.refreshing_figure.connect( lambda: self.axis.set_xscale(get_box_value(x_scale_box))) x_axis_layout.addRow("Scale", x_scale_box) # Y-AXIS # Create a group box for the Y-axis y_axis_group = GW.QGroupBox("Y-axis") layout.addRow(y_axis_group) y_axis_layout = GL.QFormLayout(y_axis_group) # Make a box for setting the label on the y-axis y_label_box = GW.FigureLabelBox() y_label_box[0].setToolTip("Label of the Y-axis") y_label_box[1].setToolTip("Label size") set_box_value(y_label_box, ('', { 'fontsize': rcParams['axes.labelsize'] })) self.add_options_entry(y_label_box) self.refreshing_figure.connect(lambda: self.axis.set_ylabel( *get_box_value(y_label_box, str, dict))) y_axis_layout.addRow("Label", y_label_box) self.y_label_box = y_label_box # Make a box for setting the range on the y-axis y_range_box = GW.DualLineEdit((float, float), r"<html>≤ Y ≤</html>") y_min_box, y_max_box = y_range_box[:] y_min_box.setToolTip("Minimum value of the Y-axis") y_max_box.setToolTip("Maximum value of the Y-axis") set_box_value(y_range_box, self.axis.get_ylim()) # Connect signals for y_range_box self.refreshing_figure.connect( lambda: self.axis.set_ylim(*get_box_value(y_range_box), auto=None)) self.axis.callbacks.connect( 'ylim_changed', lambda y: set_box_value(y_range_box, y.get_ylim())) # Make togglebox for enabling/disabling the use of this range y_range_togglebox = GW.ToggleBox( y_range_box, tooltip="Check to manually set the Y-axis range") self.add_options_entry(y_range_togglebox) y_axis_layout.addRow("Range", y_range_togglebox) # Connect signals for y_range_togglebox self.refreshing_figure.connect(lambda: self.axis.set_autoscaley_on( not get_box_value(y_range_togglebox, bool))) # Make a box for setting the scale on the y-axis y_scale_box = GW.QComboBox() y_scale_box.addItems(['linear', 'log', 'symlog', 'logit']) y_scale_box.setToolTip("Value scale of the Y-axis") self.add_options_entry(y_scale_box) self.refreshing_figure.connect( lambda: self.axis.set_yscale(get_box_value(y_scale_box))) y_axis_layout.addRow("Scale", y_scale_box) # PROPS # Create a group box for figure properties props_group = GW.QGroupBox("Properties") layout.addRow(props_group) props_layout = GL.QFormLayout(props_group) # Make a combobox for choosing the location of the legend legend_loc_box = GW.QComboBox() legend_loc_box.addItems(mpl.legend.Legend.codes.keys()) legend_loc_box.setToolTip("Location of the figure legend") set_box_value(legend_loc_box, rcParams['legend.loc']) # Make a togglebox for using a legend legend_togglebox = GW.ToggleBox( legend_loc_box, "Legend", tooltip="Toggle the use of a figure legend") self.add_options_entry(legend_togglebox) props_layout.addRow(legend_togglebox) self.legend_togglebox = legend_togglebox # Return tab return (tab, "Figure")
def create_value_box(self, name_box): """ Creates a value box for the provided `name_box` and its corresponding current value, and replaces the current value box with it. If the current value of the given `name_box` does not have a specific value box defined, a :class:`~guipy.widgets.LongGenericBox` is used instead. """ # Determine the current value of the name_box entry_name = get_box_value(name_box) # Determine at what index the provided name_box currently is in grid index = self.entries_grid.indexOf(name_box) # Check if the name_box is valid valid = self.is_valid(name_box) # Retrieve which value_box is currently there cur_box = self.entries_grid.itemAt(index + 1).widget() # Obtain the widget class associated with this entry_name if valid: # If the given name is valid, obtain it from dict or use default new_box_class = self.entry_types.get(entry_name, GW.LongGenericBox) else: # If invalid, use a label new_box_class = GW.QLabel # Check if a modified signal must be emitted later emit_signal = False if valid or type(cur_box) is not GW.QLabel: emit_signal = True # If the current value box is not this box type already, replace it if type(cur_box) is not new_box_class: # If not, create new value box new_box = new_box_class() new_box.setSizePolicy(QW.QSizePolicy.MinimumExpanding, QW.QSizePolicy.Fixed) # Connect to modified signal if valid: get_modified_signal(new_box).connect(self.modified) # Replace cur_box with new_box item = self.entries_grid.replaceWidget(cur_box, new_box) cur_box = new_box # Close the widget in this item and delete it item.widget().close() del item # If the box is invalid, set its value if not valid: # If it has a name, set a warning as the value if entry_name: set_box_value( cur_box, f"Entry <b>{entry_name}</b> is either " "invalid or already in use!") # Else, set an empty string as the value else: set_box_value(cur_box, "") # If this entry is valid, perform a few extra tasks if valid: # Modify tooltip cur_box.setToolTip(f"Set value for entry <b>{entry_name}</b>") # If this entry has a default value, use it if entry_name in self.entry_defaults: set_box_value(cur_box, self.entry_defaults[entry_name]) # Emit modified signal if required if emit_signal: self.modified.emit()